GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / staging / lustre / include / linux / libcfs / libcfs_crypto.h
1 /* GPL HEADER START
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 only,
7  * as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License version 2 for more details (a copy is included
13  * in the LICENSE file that accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License
16  * version 2 along with this program; If not, see http://www.gnu.org/licenses
17  *
18  * Please  visit http://www.xyratex.com/contact if you need additional
19  * information or have any questions.
20  *
21  * GPL HEADER END
22  */
23
24 /*
25  * Copyright 2012 Xyratex Technology Limited
26  */
27
28 #ifndef _LIBCFS_CRYPTO_H
29 #define _LIBCFS_CRYPTO_H
30
31 struct cfs_crypto_hash_type {
32         char            *cht_name;      /*< hash algorithm name, equal to
33                                          * format name for crypto api
34                                          */
35         unsigned int    cht_key;        /*< init key by default (valid for
36                                          * 4 bytes context like crc32, adler
37                                          */
38         unsigned int    cht_size;       /**< hash digest size */
39 };
40
41 enum cfs_crypto_hash_alg {
42         CFS_HASH_ALG_NULL       = 0,
43         CFS_HASH_ALG_ADLER32,
44         CFS_HASH_ALG_CRC32,
45         CFS_HASH_ALG_MD5,
46         CFS_HASH_ALG_SHA1,
47         CFS_HASH_ALG_SHA256,
48         CFS_HASH_ALG_SHA384,
49         CFS_HASH_ALG_SHA512,
50         CFS_HASH_ALG_CRC32C,
51         CFS_HASH_ALG_MAX,
52         CFS_HASH_ALG_UNKNOWN    = 0xff
53 };
54
55 static struct cfs_crypto_hash_type hash_types[] = {
56         [CFS_HASH_ALG_NULL] = {
57                 .cht_name       = "null",
58                 .cht_key        = 0,
59                 .cht_size       = 0
60         },
61         [CFS_HASH_ALG_ADLER32] = {
62                 .cht_name       = "adler32",
63                 .cht_key        = 1,
64                 .cht_size       = 4
65         },
66         [CFS_HASH_ALG_CRC32] = {
67                 .cht_name       = "crc32",
68                 .cht_key        = ~0,
69                 .cht_size       = 4
70         },
71         [CFS_HASH_ALG_CRC32C] = {
72                 .cht_name       = "crc32c",
73                 .cht_key        = ~0,
74                 .cht_size       = 4
75         },
76         [CFS_HASH_ALG_MD5] = {
77                 .cht_name       = "md5",
78                 .cht_key        = 0,
79                 .cht_size       = 16
80         },
81         [CFS_HASH_ALG_SHA1] = {
82                 .cht_name       = "sha1",
83                 .cht_key        = 0,
84                 .cht_size       = 20
85         },
86         [CFS_HASH_ALG_SHA256] = {
87                 .cht_name       = "sha256",
88                 .cht_key        = 0,
89                 .cht_size       = 32
90         },
91         [CFS_HASH_ALG_SHA384] = {
92                 .cht_name       = "sha384",
93                 .cht_key        = 0,
94                 .cht_size       = 48
95         },
96         [CFS_HASH_ALG_SHA512] = {
97                 .cht_name       = "sha512",
98                 .cht_key        = 0,
99                 .cht_size       = 64
100         },
101         [CFS_HASH_ALG_MAX] = {
102                 .cht_name       = NULL,
103                 .cht_key        = 0,
104                 .cht_size       = 64
105         },
106 };
107
108 /* Maximum size of hash_types[].cht_size */
109 #define CFS_CRYPTO_HASH_DIGESTSIZE_MAX  64
110
111 /**
112  * Return hash algorithm information for the specified algorithm identifier
113  *
114  * Hash information includes algorithm name, initial seed, hash size.
115  *
116  * \retval      cfs_crypto_hash_type for valid ID (CFS_HASH_ALG_*)
117  * \retval      NULL for unknown algorithm identifier
118  */
119 static inline const struct cfs_crypto_hash_type *
120 cfs_crypto_hash_type(enum cfs_crypto_hash_alg hash_alg)
121 {
122         struct cfs_crypto_hash_type *ht;
123
124         if (hash_alg < CFS_HASH_ALG_MAX) {
125                 ht = &hash_types[hash_alg];
126                 if (ht->cht_name)
127                         return ht;
128         }
129         return NULL;
130 }
131
132 /**
133  * Return hash name for hash algorithm identifier
134  *
135  * \param[in]   hash_alg hash alrgorithm id (CFS_HASH_ALG_*)
136  *
137  * \retval      string name of known hash algorithm
138  * \retval      "unknown" if hash algorithm is unknown
139  */
140 static inline const char *
141 cfs_crypto_hash_name(enum cfs_crypto_hash_alg hash_alg)
142 {
143         const struct cfs_crypto_hash_type *ht;
144
145         ht = cfs_crypto_hash_type(hash_alg);
146         if (ht)
147                 return ht->cht_name;
148         return "unknown";
149 }
150
151 /**
152  * Return digest size for hash algorithm type
153  *
154  * \param[in]   hash_alg hash alrgorithm id (CFS_HASH_ALG_*)
155  *
156  * \retval      hash algorithm digest size in bytes
157  * \retval      0 if hash algorithm type is unknown
158  */
159 static inline int cfs_crypto_hash_digestsize(enum cfs_crypto_hash_alg hash_alg)
160 {
161         const struct cfs_crypto_hash_type *ht;
162
163         ht = cfs_crypto_hash_type(hash_alg);
164         if (ht)
165                 return ht->cht_size;
166         return 0;
167 }
168
169 /**
170  * Find hash algorithm ID for the specified algorithm name
171  *
172  * \retval      hash algorithm ID for valid ID (CFS_HASH_ALG_*)
173  * \retval      CFS_HASH_ALG_UNKNOWN for unknown algorithm name
174  */
175 static inline unsigned char cfs_crypto_hash_alg(const char *algname)
176 {
177         enum cfs_crypto_hash_alg hash_alg;
178
179         for (hash_alg = 0; hash_alg < CFS_HASH_ALG_MAX; hash_alg++)
180                 if (!strcmp(hash_types[hash_alg].cht_name, algname))
181                         return hash_alg;
182
183         return CFS_HASH_ALG_UNKNOWN;
184 }
185
186 int cfs_crypto_hash_digest(enum cfs_crypto_hash_alg hash_alg,
187                            const void *buf, unsigned int buf_len,
188                            unsigned char *key, unsigned int key_len,
189                            unsigned char *hash, unsigned int *hash_len);
190
191 /* cfs crypto hash descriptor */
192 struct cfs_crypto_hash_desc;
193
194 struct cfs_crypto_hash_desc *
195 cfs_crypto_hash_init(enum cfs_crypto_hash_alg hash_alg,
196                      unsigned char *key, unsigned int key_len);
197 int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
198                                 struct page *page, unsigned int offset,
199                                 unsigned int len);
200 int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
201                            unsigned int buf_len);
202 int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
203                           unsigned char *hash, unsigned int *hash_len);
204 int cfs_crypto_register(void);
205 void cfs_crypto_unregister(void);
206 int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg);
207 #endif