Whamcloud - gitweb
LU-17744 ldiskfs: mballoc stats fixes
[fs/lustre-release.git] / libcfs / include / 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  * Copyright (c) 2014, Intel Corporation.
28  */
29
30 #ifndef _LIBCFS_CRYPTO_H
31 #define _LIBCFS_CRYPTO_H
32
33 struct cfs_crypto_hash_type {
34         char            *cht_name;      /**< hash algorithm name, equal to
35                                          * format name for crypto api */
36         unsigned int    cht_key;        /**< init key by default (vaild for
37                                          * 4 bytes context like crc32, adler */
38         unsigned int    cht_size;       /**< hash digest size */
39 };
40
41 struct cfs_crypto_crypt_type {
42         char           *cct_name;         /**< crypto algorithm name, equal to
43                                            * format name for crypto api */
44         unsigned int    cct_size;         /**< crypto key size */
45 };
46
47 enum cfs_crypto_hash_alg {
48         CFS_HASH_ALG_NULL       = 0,
49         CFS_HASH_ALG_ADLER32,
50         CFS_HASH_ALG_CRC32,
51         CFS_HASH_ALG_CRC32C,
52         /* hashes before here will be speed-tested at module load */
53         CFS_HASH_ALG_MD5,
54         CFS_HASH_ALG_SHA1,
55         CFS_HASH_ALG_SHA256,
56         CFS_HASH_ALG_SHA384,
57         CFS_HASH_ALG_SHA512,
58         CFS_HASH_ALG_MAX,
59         CFS_HASH_ALG_SPEED_MAX = CFS_HASH_ALG_MD5,
60         CFS_HASH_ALG_UNKNOWN    = 0xff
61 };
62
63 enum cfs_crypto_crypt_alg {
64         CFS_CRYPT_ALG_NULL      = 0,
65         CFS_CRYPT_ALG_AES256_CTR,
66         CFS_CRYPT_ALG_MAX,
67         CFS_CRYPT_ALG_UNKNOWN   = 0xff
68 };
69
70 static struct cfs_crypto_hash_type hash_types[] = {
71         [CFS_HASH_ALG_NULL] = {
72                 .cht_name       = "null",
73                 .cht_key        = 0,
74                 .cht_size       = 0
75         },
76         [CFS_HASH_ALG_ADLER32] = {
77                 .cht_name       = "adler32",
78                 .cht_key        = 1,
79                 .cht_size       = 4
80         },
81         [CFS_HASH_ALG_CRC32] = {
82                 .cht_name       = "crc32",
83                 .cht_key        = ~0,
84                 .cht_size       = 4
85         },
86         [CFS_HASH_ALG_CRC32C] = {
87                 .cht_name       = "crc32c",
88                 .cht_key        = ~0,
89                 .cht_size       = 4
90         },
91         [CFS_HASH_ALG_MD5] = {
92                 .cht_name       = "md5",
93                 .cht_key        = 0,
94                 .cht_size       = 16
95         },
96         [CFS_HASH_ALG_SHA1] = {
97                 .cht_name       = "sha1",
98                 .cht_key        = 0,
99                 .cht_size       = 20
100         },
101         [CFS_HASH_ALG_SHA256] = {
102                 .cht_name       = "sha256",
103                 .cht_key        = 0,
104                 .cht_size       = 32
105         },
106         [CFS_HASH_ALG_SHA384] = {
107                 .cht_name       = "sha384",
108                 .cht_key        = 0,
109                 .cht_size       = 48
110         },
111         [CFS_HASH_ALG_SHA512] = {
112                 .cht_name       = "sha512",
113                 .cht_key        = 0,
114                 .cht_size       = 64
115         },
116         [CFS_HASH_ALG_MAX] = {
117                 .cht_name       = NULL,
118                 .cht_key        = 0,
119                 .cht_size       = 64
120         }
121 };
122
123 static struct cfs_crypto_crypt_type crypt_types[] = {
124         [CFS_CRYPT_ALG_NULL] = {
125                 .cct_name       = "null",
126                 .cct_size       = 0
127         },
128         [CFS_CRYPT_ALG_AES256_CTR] = {
129                 .cct_name       = "ctr(aes)",
130                 .cct_size       = 32
131         }
132 };
133
134 /* Maximum size of hash_types[].cht_size */
135 #define CFS_CRYPTO_HASH_DIGESTSIZE_MAX 64
136
137 /*  Array of hash algorithm speed in MByte per second */
138 extern int cfs_crypto_hash_speeds[CFS_HASH_ALG_MAX];
139
140 /**
141  * Return hash algorithm information for the specified algorithm identifier
142  *
143  * Hash information includes algorithm name, initial seed, hash size.
144  *
145  * \retval              cfs_crypto_hash_type for valid ID (CFS_HASH_ALG_*)
146  * \retval              NULL for unknown algorithm identifier
147  */
148 static inline const struct
149 cfs_crypto_hash_type *cfs_crypto_hash_type(enum cfs_crypto_hash_alg hash_alg)
150 {
151         struct cfs_crypto_hash_type *ht;
152
153         if (hash_alg < CFS_HASH_ALG_MAX) {
154                 ht = &hash_types[hash_alg];
155                 if (ht->cht_name != NULL)
156                         return ht;
157         }
158         return NULL;
159 }
160
161 /**
162  * Return hash name for hash algorithm identifier
163  *
164  * \param[in] hash_alg  hash alrgorithm id (CFS_HASH_ALG_*)
165  *
166  * \retval              string name of known hash algorithm
167  * \retval              "unknown" if hash algorithm is unknown
168  */
169 static inline const
170 char *cfs_crypto_hash_name(enum cfs_crypto_hash_alg hash_alg)
171 {
172         const struct cfs_crypto_hash_type *ht;
173
174         ht = cfs_crypto_hash_type(hash_alg);
175         if (ht)
176                 return ht->cht_name;
177
178         return "unknown";
179 }
180
181 /**
182  * Return digest size for hash algorithm type
183  *
184  * \param[in] hash_alg  hash alrgorithm id (CFS_HASH_ALG_*)
185  *
186  * \retval              hash algorithm digest size in bytes
187  * \retval              0 if hash algorithm type is unknown
188  */
189 static inline
190 unsigned int cfs_crypto_hash_digestsize(enum cfs_crypto_hash_alg hash_alg)
191 {
192         const struct cfs_crypto_hash_type *ht;
193
194         ht = cfs_crypto_hash_type(hash_alg);
195         if (ht != NULL)
196                 return ht->cht_size;
197
198         return 0;
199 }
200
201 /**
202  * Find hash algorithm ID for the specified algorithm name
203  *
204  * \retval              hash algorithm ID for valid ID (CFS_HASH_ALG_*)
205  * \retval              CFS_HASH_ALG_UNKNOWN for unknown algorithm name
206  */
207 static inline unsigned char cfs_crypto_hash_alg(const char *algname)
208 {
209         enum cfs_crypto_hash_alg hash_alg;
210
211         for (hash_alg = 0; hash_alg < CFS_HASH_ALG_MAX; hash_alg++)
212                 if (strcmp(hash_types[hash_alg].cht_name, algname) == 0)
213                         return hash_alg;
214
215         return CFS_HASH_ALG_UNKNOWN;
216 }
217
218 /**
219  * Return crypt algorithm information for the specified algorithm identifier
220  *
221  * Crypt information includes algorithm name, key size.
222  *
223  * \retval              cfs_crypto_crupt_type for valid ID (CFS_CRYPT_ALG_*)
224  * \retval              NULL for unknown algorithm identifier
225  */
226 static inline const struct
227 cfs_crypto_crypt_type *cfs_crypto_crypt_type(
228         enum cfs_crypto_crypt_alg crypt_alg)
229 {
230         struct cfs_crypto_crypt_type *ct;
231
232         if (crypt_alg < CFS_CRYPT_ALG_MAX) {
233                 ct = &crypt_types[crypt_alg];
234                 if (ct->cct_name != NULL)
235                         return ct;
236         }
237         return NULL;
238 }
239
240 /**
241  * Return crypt name for crypt algorithm identifier
242  *
243  * \param[in] crypt_alg crypt alrgorithm id (CFS_CRYPT_ALG_*)
244  *
245  * \retval              string name of known crypt algorithm
246  * \retval              "unknown" if hash algorithm is unknown
247  */
248 static inline const
249 char *cfs_crypto_crypt_name(enum cfs_crypto_crypt_alg crypt_alg)
250 {
251         const struct cfs_crypto_crypt_type *ct;
252
253         ct = cfs_crypto_crypt_type(crypt_alg);
254         if (ct)
255                 return ct->cct_name;
256
257         return "unknown";
258 }
259
260
261 /**
262  * Return key size for crypto algorithm type
263  *
264  * \param[in] crypt_alg crypt alrgorithm id (CFS_CRYPT_ALG_*)
265  *
266  * \retval              crypt algorithm key size in bytes
267  * \retval              0 if crypt algorithm type is unknown
268  */
269 static inline
270 unsigned int cfs_crypto_crypt_keysize(enum cfs_crypto_crypt_alg crypt_alg)
271 {
272         const struct cfs_crypto_crypt_type *ct;
273
274         ct = cfs_crypto_crypt_type(crypt_alg);
275         if (ct != NULL)
276                 return ct->cct_size;
277
278         return 0;
279 }
280
281 /**
282  * Find crypto algorithm ID for the specified algorithm name
283  *
284  * \retval              crypto algorithm ID for valid ID (CFS_CRYPT_ALG_*)
285  * \retval              CFS_CRYPT_ALG_UNKNOWN for unknown algorithm name
286  */
287 static inline unsigned char cfs_crypto_crypt_alg(const char *algname)
288 {
289         enum cfs_crypto_crypt_alg crypt_alg;
290
291         for (crypt_alg = 0; crypt_alg < CFS_CRYPT_ALG_MAX; crypt_alg++)
292                 if (strcmp(crypt_types[crypt_alg].cct_name, algname) == 0)
293                         return crypt_alg;
294
295         return CFS_CRYPT_ALG_UNKNOWN;
296 }
297
298 int cfs_crypto_hash_digest(enum cfs_crypto_hash_alg hash_alg,
299                            const void *buf, unsigned int buf_len,
300                            unsigned char *key, unsigned int key_len,
301                            unsigned char *hash, unsigned int *hash_len);
302
303 /* cfs crypto hash descriptor */
304 struct page;
305
306 struct ahash_request *
307         cfs_crypto_hash_init(enum cfs_crypto_hash_alg hash_alg,
308                              unsigned char *key, unsigned int key_len);
309 int cfs_crypto_hash_update_page(struct ahash_request *req,
310                                 struct page *page, unsigned int offset,
311                                 unsigned int len);
312 int cfs_crypto_hash_update(struct ahash_request *req, const void *buf,
313                            unsigned int buf_len);
314 int cfs_crypto_hash_final(struct ahash_request *req,
315                           unsigned char *hash, unsigned int *hash_len);
316 int cfs_crypto_register(void);
317 void cfs_crypto_unregister(void);
318 int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg);
319 #endif