Whamcloud - gitweb
LU-11089 obdclass: remove locking from lu_context_exit()
[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 /**
138  * Return hash algorithm information for the specified algorithm identifier
139  *
140  * Hash information includes algorithm name, initial seed, hash size.
141  *
142  * \retval              cfs_crypto_hash_type for valid ID (CFS_HASH_ALG_*)
143  * \retval              NULL for unknown algorithm identifier
144  */
145 static inline const struct
146 cfs_crypto_hash_type *cfs_crypto_hash_type(enum cfs_crypto_hash_alg hash_alg)
147 {
148         struct cfs_crypto_hash_type *ht;
149
150         if (hash_alg < CFS_HASH_ALG_MAX) {
151                 ht = &hash_types[hash_alg];
152                 if (ht->cht_name != NULL)
153                         return ht;
154         }
155         return NULL;
156 }
157
158 /**
159  * Return hash name for hash algorithm identifier
160  *
161  * \param[in] hash_alg  hash alrgorithm id (CFS_HASH_ALG_*)
162  *
163  * \retval              string name of known hash algorithm
164  * \retval              "unknown" if hash algorithm is unknown
165  */
166 static inline const
167 char *cfs_crypto_hash_name(enum cfs_crypto_hash_alg hash_alg)
168 {
169         const struct cfs_crypto_hash_type *ht;
170
171         ht = cfs_crypto_hash_type(hash_alg);
172         if (ht)
173                 return ht->cht_name;
174
175         return "unknown";
176 }
177
178 /**
179  * Return digest size for hash algorithm type
180  *
181  * \param[in] hash_alg  hash alrgorithm id (CFS_HASH_ALG_*)
182  *
183  * \retval              hash algorithm digest size in bytes
184  * \retval              0 if hash algorithm type is unknown
185  */
186 static inline
187 unsigned int cfs_crypto_hash_digestsize(enum cfs_crypto_hash_alg hash_alg)
188 {
189         const struct cfs_crypto_hash_type *ht;
190
191         ht = cfs_crypto_hash_type(hash_alg);
192         if (ht != NULL)
193                 return ht->cht_size;
194
195         return 0;
196 }
197
198 /**
199  * Find hash algorithm ID for the specified algorithm name
200  *
201  * \retval              hash algorithm ID for valid ID (CFS_HASH_ALG_*)
202  * \retval              CFS_HASH_ALG_UNKNOWN for unknown algorithm name
203  */
204 static inline unsigned char cfs_crypto_hash_alg(const char *algname)
205 {
206         enum cfs_crypto_hash_alg hash_alg;
207
208         for (hash_alg = 0; hash_alg < CFS_HASH_ALG_MAX; hash_alg++)
209                 if (strcmp(hash_types[hash_alg].cht_name, algname) == 0)
210                         return hash_alg;
211
212         return CFS_HASH_ALG_UNKNOWN;
213 }
214
215 /**
216  * Return crypt algorithm information for the specified algorithm identifier
217  *
218  * Crypt information includes algorithm name, key size.
219  *
220  * \retval              cfs_crypto_crupt_type for valid ID (CFS_CRYPT_ALG_*)
221  * \retval              NULL for unknown algorithm identifier
222  */
223 static inline const struct
224 cfs_crypto_crypt_type *cfs_crypto_crypt_type(
225         enum cfs_crypto_crypt_alg crypt_alg)
226 {
227         struct cfs_crypto_crypt_type *ct;
228
229         if (crypt_alg < CFS_CRYPT_ALG_MAX) {
230                 ct = &crypt_types[crypt_alg];
231                 if (ct->cct_name != NULL)
232                         return ct;
233         }
234         return NULL;
235 }
236
237 /**
238  * Return crypt name for crypt algorithm identifier
239  *
240  * \param[in] crypt_alg crypt alrgorithm id (CFS_CRYPT_ALG_*)
241  *
242  * \retval              string name of known crypt algorithm
243  * \retval              "unknown" if hash algorithm is unknown
244  */
245 static inline const
246 char *cfs_crypto_crypt_name(enum cfs_crypto_crypt_alg crypt_alg)
247 {
248         const struct cfs_crypto_crypt_type *ct;
249
250         ct = cfs_crypto_crypt_type(crypt_alg);
251         if (ct)
252                 return ct->cct_name;
253
254         return "unknown";
255 }
256
257
258 /**
259  * Return key size for crypto algorithm type
260  *
261  * \param[in] crypt_alg crypt alrgorithm id (CFS_CRYPT_ALG_*)
262  *
263  * \retval              crypt algorithm key size in bytes
264  * \retval              0 if crypt algorithm type is unknown
265  */
266 static inline
267 unsigned int cfs_crypto_crypt_keysize(enum cfs_crypto_crypt_alg crypt_alg)
268 {
269         const struct cfs_crypto_crypt_type *ct;
270
271         ct = cfs_crypto_crypt_type(crypt_alg);
272         if (ct != NULL)
273                 return ct->cct_size;
274
275         return 0;
276 }
277
278 /**
279  * Find crypto algorithm ID for the specified algorithm name
280  *
281  * \retval              crypto algorithm ID for valid ID (CFS_CRYPT_ALG_*)
282  * \retval              CFS_CRYPT_ALG_UNKNOWN for unknown algorithm name
283  */
284 static inline unsigned char cfs_crypto_crypt_alg(const char *algname)
285 {
286         enum cfs_crypto_crypt_alg crypt_alg;
287
288         for (crypt_alg = 0; crypt_alg < CFS_CRYPT_ALG_MAX; crypt_alg++)
289                 if (strcmp(crypt_types[crypt_alg].cct_name, algname) == 0)
290                         return crypt_alg;
291
292         return CFS_CRYPT_ALG_UNKNOWN;
293 }
294
295 int cfs_crypto_hash_digest(enum cfs_crypto_hash_alg hash_alg,
296                            const void *buf, unsigned int buf_len,
297                            unsigned char *key, unsigned int key_len,
298                            unsigned char *hash, unsigned int *hash_len);
299
300 /* cfs crypto hash descriptor */
301 struct page;
302
303 struct ahash_request *
304         cfs_crypto_hash_init(enum cfs_crypto_hash_alg hash_alg,
305                              unsigned char *key, unsigned int key_len);
306 int cfs_crypto_hash_update_page(struct ahash_request *req,
307                                 struct page *page, unsigned int offset,
308                                 unsigned int len);
309 int cfs_crypto_hash_update(struct ahash_request *req, const void *buf,
310                            unsigned int buf_len);
311 int cfs_crypto_hash_final(struct ahash_request *req,
312                           unsigned char *hash, unsigned int *hash_len);
313 int cfs_crypto_register(void);
314 void cfs_crypto_unregister(void);
315 int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg);
316 #endif