Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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         unsigned int    cht_key;        /**< init key by default (valid 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         return "unknown";
87 }
88
89 /**     Return digest size for valid algorithm identifier or 0 */
90 static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg)
91 {
92         const struct cfs_crypto_hash_type *ht;
93
94         ht = cfs_crypto_hash_type(hash_alg);
95         if (ht)
96                 return ht->cht_size;
97         return 0;
98 }
99
100 /**     Return hash identifier for valid hash algorithm name or 0xFF */
101 static inline unsigned char cfs_crypto_hash_alg(const char *algname)
102 {
103         unsigned char   i;
104
105         for (i = 0; i < CFS_HASH_ALG_MAX; i++)
106                 if (!strcmp(hash_types[i].cht_name, algname))
107                         break;
108         return (i == CFS_HASH_ALG_MAX ? 0xFF : i);
109 }
110
111 /**     Calculate hash digest for buffer.
112  *      @param alg          id of hash algorithm
113  *      @param buf          buffer of data
114  *      @param buf_len  buffer len
115  *      @param key          initial value for algorithm, if it is NULL,
116  *                          default initial value should be used.
117  *      @param key_len  len of initial value
118  *      @param hash        [out] pointer to hash, if it is NULL, hash_len is
119  *                          set to valid digest size in bytes, retval -ENOSPC.
120  *      @param hash_len       [in,out] size of hash buffer
121  *      @returns              status of operation
122  *      @retval -EINVAL       if buf, buf_len, hash_len or alg_id is invalid
123  *      @retval -ENODEV       if this algorithm is unsupported
124  *      @retval -ENOSPC       if pointer to hash is NULL, or hash_len less than
125  *                          digest size
126  *      @retval 0            for success
127  *      @retval < 0        other errors from lower layers.
128  */
129 int cfs_crypto_hash_digest(unsigned char alg,
130                            const void *buf, unsigned int buf_len,
131                            unsigned char *key, unsigned int key_len,
132                            unsigned char *hash, unsigned int *hash_len);
133
134 /* cfs crypto hash descriptor */
135 struct cfs_crypto_hash_desc;
136
137 /**     Allocate and initialize descriptor for hash algorithm.
138  *      @param alg          algorithm id
139  *      @param key          initial value for algorithm, if it is NULL,
140  *                          default initial value should be used.
141  *      @param key_len  len of initial value
142  *      @returns              pointer to descriptor of hash instance
143  *      @retval ERR_PTR(error) when errors occurred.
144  */
145 struct cfs_crypto_hash_desc*
146         cfs_crypto_hash_init(unsigned char alg,
147                              unsigned char *key, unsigned int key_len);
148
149 /**    Update digest by part of data.
150  *     @param desc            hash descriptor
151  *     @param page            data page
152  *     @param offset        data offset
153  *     @param len              data len
154  *     @returns          status of operation
155  *     @retval 0                for success.
156  */
157 int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
158                                 struct page *page, unsigned int offset,
159                                 unsigned int len);
160
161 /**    Update digest by part of data.
162  *     @param desc            hash descriptor
163  *     @param buf              pointer to data buffer
164  *     @param buf_len      size of data at buffer
165  *     @returns          status of operation
166  *     @retval 0                for success.
167  */
168 int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
169                            unsigned int buf_len);
170
171 /**    Finalize hash calculation, copy hash digest to buffer, destroy hash
172  *     descriptor.
173  *     @param desc            hash descriptor
174  *     @param hash            buffer pointer to store hash digest
175  *     @param hash_len    pointer to hash buffer size, if NULL
176  *                            destroy hash descriptor
177  *     @returns          status of operation
178  *     @retval -ENOSPC    if hash is NULL, or *hash_len less than
179  *                            digest size
180  *     @retval 0                for success
181  *     @retval < 0            other errors from lower layers.
182  */
183 int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
184                           unsigned char *hash, unsigned int *hash_len);
185 /**
186  *      Register crypto hash algorithms
187  */
188 int cfs_crypto_register(void);
189
190 /**
191  *      Unregister
192  */
193 void cfs_crypto_unregister(void);
194
195 /**     Return hash speed in Mbytes per second for valid hash algorithm
196  *      identifier. If test was unsuccessful -1 would be returned.
197  */
198 int cfs_crypto_hash_speed(unsigned char hash_alg);
199 #endif