Whamcloud - gitweb
LU-2675 cleanup: remove unused mkdirdeep.c and lltrace.h
[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
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         unsigned int    cht_key;        /**< init key by default (vaild for
35                                          * 4 bytes context like crc32, adler */
36         unsigned int    cht_size;       /**< hash digest size */
37 };
38
39 enum cfs_crypto_hash_alg {
40         CFS_HASH_ALG_NULL       = 0,
41         CFS_HASH_ALG_ADLER32,
42         CFS_HASH_ALG_CRC32,
43         CFS_HASH_ALG_MD5,
44         CFS_HASH_ALG_SHA1,
45         CFS_HASH_ALG_SHA256,
46         CFS_HASH_ALG_SHA384,
47         CFS_HASH_ALG_SHA512,
48         CFS_HASH_ALG_CRC32C,
49         CFS_HASH_ALG_MAX
50 };
51
52 static struct cfs_crypto_hash_type hash_types[] = {
53         [CFS_HASH_ALG_NULL]    = { "null",     0,      0 },
54         [CFS_HASH_ALG_ADLER32] = { "adler32",  1,      4 },
55         [CFS_HASH_ALG_CRC32]   = { "crc32",   ~0,      4 },
56         [CFS_HASH_ALG_CRC32C]  = { "crc32c",  ~0,      4 },
57         [CFS_HASH_ALG_MD5]     = { "md5",      0,     16 },
58         [CFS_HASH_ALG_SHA1]    = { "sha1",     0,     20 },
59         [CFS_HASH_ALG_SHA256]  = { "sha256",   0,     32 },
60         [CFS_HASH_ALG_SHA384]  = { "sha384",   0,     48 },
61         [CFS_HASH_ALG_SHA512]  = { "sha512",   0,     64 },
62 };
63
64 /**    Return pointer to type of hash for valid hash algorithm identifier */
65 static inline const struct cfs_crypto_hash_type *
66                     cfs_crypto_hash_type(unsigned char hash_alg)
67 {
68         struct cfs_crypto_hash_type *ht;
69
70         if (hash_alg < CFS_HASH_ALG_MAX) {
71                 ht = &hash_types[hash_alg];
72                 if (ht->cht_name)
73                         return ht;
74         }
75         return NULL;
76 }
77
78 /**     Return hash name for valid hash algorithm identifier or "unknown" */
79 static inline const char *cfs_crypto_hash_name(unsigned char hash_alg)
80 {
81         const struct cfs_crypto_hash_type *ht;
82
83         ht = cfs_crypto_hash_type(hash_alg);
84         if (ht)
85                 return ht->cht_name;
86         else
87                 return "unknown";
88 }
89
90 /**     Return digest size for valid algorithm identifier or 0 */
91 static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg)
92 {
93         const struct cfs_crypto_hash_type *ht;
94
95         ht = cfs_crypto_hash_type(hash_alg);
96         if (ht)
97                 return ht->cht_size;
98         else
99                 return 0;
100 }
101
102 /**     Return hash identifier for valid hash algorithm name or 0xFF */
103 static inline unsigned char cfs_crypto_hash_alg(const char *algname)
104 {
105         unsigned char   i;
106
107         for (i = 0; i < CFS_HASH_ALG_MAX; i++)
108                 if (!strcmp(hash_types[i].cht_name, algname))
109                         break;
110         return (i == CFS_HASH_ALG_MAX ? 0xFF : i);
111 }
112
113 /**     Calculate hash digest for buffer.
114  *      @param alg          id of hash algorithm
115  *      @param buf          buffer of data
116  *      @param buf_len  buffer len
117  *      @param key          initial value for algorithm, if it is NULL,
118  *                          default initial value should be used.
119  *      @param key_len  len of initial value
120  *      @param hash        [out] pointer to hash, if it is NULL, hash_len is
121  *                          set to valid digest size in bytes, retval -ENOSPC.
122  *      @param hash_len       [in,out] size of hash buffer
123  *      @returns              status of operation
124  *      @retval -EINVAL       if buf, buf_len, hash_len or alg_id is invalid
125  *      @retval -ENODEV       if this algorithm is unsupported
126  *      @retval -ENOSPC       if pointer to hash is NULL, or hash_len less than
127  *                          digest size
128  *      @retval 0            for success
129  *      @retval < 0        other errors from lower layers.
130  */
131 int cfs_crypto_hash_digest(unsigned char alg,
132                            const void *buf, unsigned int buf_len,
133                            unsigned char *key, unsigned int key_len,
134                            unsigned char *hash, unsigned int *hash_len);
135
136 /* cfs crypto hash descriptor */
137 struct cfs_crypto_hash_desc;
138
139 /**     Allocate and initialize desriptor for hash algorithm.
140  *      @param alg          algorithm id
141  *      @param key          initial value for algorithm, if it is NULL,
142  *                          default initial value should be used.
143  *      @param key_len  len of initial value
144  *      @returns              pointer to descriptor of hash instance
145  *      @retval ERR_PTR(error) when errors occured.
146  */
147 struct cfs_crypto_hash_desc*
148         cfs_crypto_hash_init(unsigned char alg,
149                              unsigned char *key, unsigned int key_len);
150
151 /**    Update digest by part of data.
152  *     @param desc            hash descriptor
153  *     @param page            data page
154  *     @param offset        data offset
155  *     @param len              data len
156  *     @returns          status of operation
157  *     @retval 0                for success.
158  */
159 int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
160                                 cfs_page_t *page, unsigned int offset,
161                                 unsigned int len);
162
163 /**    Update digest by part of data.
164  *     @param desc            hash descriptor
165  *     @param buf              pointer to data buffer
166  *     @param buf_len      size of data at buffer
167  *     @returns          status of operation
168  *     @retval 0                for success.
169  */
170 int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
171                            unsigned int buf_len);
172
173 /**    Finalize hash calculation, copy hash digest to buffer, destroy hash
174  *     descriptor.
175  *     @param desc            hash descriptor
176  *     @param hash            buffer pointer to store hash digest
177  *     @param hash_len    pointer to hash buffer size, if NULL
178  *                            destory hash descriptor
179  *     @returns          status of operation
180  *     @retval -ENOSPC    if hash is NULL, or *hash_len less than
181  *                            digest size
182  *     @retval 0                for success
183  *     @retval < 0            other errors from lower layers.
184  */
185 int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
186                           unsigned char *hash, unsigned int *hash_len);
187 /**
188  *      Register crypto hash algorithms
189  */
190 int cfs_crypto_register(void);
191
192 /**
193  *      Unregister
194  */
195 void cfs_crypto_unregister(void);
196
197 /**     Return hash speed in Mbytes per second for valid hash algorithm
198  *      identifier. If test was unsuccessfull -1 would be return.
199  */
200 int cfs_crypto_hash_speed(unsigned char hash_alg);
201 #endif