GNU Linux-libre 4.9.311-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         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         CFS_HASH_ALG_UNKNOWN    = 0xff
51 };
52
53 static struct cfs_crypto_hash_type hash_types[] = {
54         [CFS_HASH_ALG_NULL]    = { "null",     0,      0 },
55         [CFS_HASH_ALG_ADLER32] = { "adler32",  1,      4 },
56         [CFS_HASH_ALG_CRC32]   = { "crc32",   ~0,      4 },
57         [CFS_HASH_ALG_CRC32C]  = { "crc32c",  ~0,      4 },
58         [CFS_HASH_ALG_MD5]     = { "md5",      0,     16 },
59         [CFS_HASH_ALG_SHA1]    = { "sha1",     0,     20 },
60         [CFS_HASH_ALG_SHA256]  = { "sha256",   0,     32 },
61         [CFS_HASH_ALG_SHA384]  = { "sha384",   0,     48 },
62         [CFS_HASH_ALG_SHA512]  = { "sha512",   0,     64 },
63         [CFS_HASH_ALG_MAX]      = { NULL,       0,      64 },
64 };
65
66 /* Maximum size of hash_types[].cht_size */
67 #define CFS_CRYPTO_HASH_DIGESTSIZE_MAX  64
68
69 /**
70  * Return hash algorithm information for the specified algorithm identifier
71  *
72  * Hash information includes algorithm name, initial seed, hash size.
73  *
74  * \retval      cfs_crypto_hash_type for valid ID (CFS_HASH_ALG_*)
75  * \retval      NULL for unknown algorithm identifier
76  */
77 static inline const struct cfs_crypto_hash_type *
78 cfs_crypto_hash_type(enum cfs_crypto_hash_alg hash_alg)
79 {
80         struct cfs_crypto_hash_type *ht;
81
82         if (hash_alg < CFS_HASH_ALG_MAX) {
83                 ht = &hash_types[hash_alg];
84                 if (ht->cht_name)
85                         return ht;
86         }
87         return NULL;
88 }
89
90 /**
91  * Return hash name for hash algorithm identifier
92  *
93  * \param[in]   hash_alg hash alrgorithm id (CFS_HASH_ALG_*)
94  *
95  * \retval      string name of known hash algorithm
96  * \retval      "unknown" if hash algorithm is unknown
97  */
98 static inline const char *
99 cfs_crypto_hash_name(enum cfs_crypto_hash_alg hash_alg)
100 {
101         const struct cfs_crypto_hash_type *ht;
102
103         ht = cfs_crypto_hash_type(hash_alg);
104         if (ht)
105                 return ht->cht_name;
106         return "unknown";
107 }
108
109 /**
110  * Return digest size for hash algorithm type
111  *
112  * \param[in]   hash_alg hash alrgorithm id (CFS_HASH_ALG_*)
113  *
114  * \retval      hash algorithm digest size in bytes
115  * \retval      0 if hash algorithm type is unknown
116  */
117 static inline int cfs_crypto_hash_digestsize(enum cfs_crypto_hash_alg hash_alg)
118 {
119         const struct cfs_crypto_hash_type *ht;
120
121         ht = cfs_crypto_hash_type(hash_alg);
122         if (ht)
123                 return ht->cht_size;
124         return 0;
125 }
126
127 /**
128  * Find hash algorithm ID for the specified algorithm name
129  *
130  * \retval      hash algorithm ID for valid ID (CFS_HASH_ALG_*)
131  * \retval      CFS_HASH_ALG_UNKNOWN for unknown algorithm name
132  */
133 static inline unsigned char cfs_crypto_hash_alg(const char *algname)
134 {
135         enum cfs_crypto_hash_alg hash_alg;
136
137         for (hash_alg = 0; hash_alg < CFS_HASH_ALG_MAX; hash_alg++)
138                 if (strcmp(hash_types[hash_alg].cht_name, algname) == 0)
139                         return hash_alg;
140
141         return CFS_HASH_ALG_UNKNOWN;
142 }
143
144 int cfs_crypto_hash_digest(enum cfs_crypto_hash_alg hash_alg,
145                            const void *buf, unsigned int buf_len,
146                            unsigned char *key, unsigned int key_len,
147                            unsigned char *hash, unsigned int *hash_len);
148
149 /* cfs crypto hash descriptor */
150 struct cfs_crypto_hash_desc;
151
152 struct cfs_crypto_hash_desc *
153 cfs_crypto_hash_init(enum cfs_crypto_hash_alg hash_alg,
154                      unsigned char *key, unsigned int key_len);
155 int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
156                                 struct page *page, unsigned int offset,
157                                 unsigned int len);
158 int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
159                            unsigned int buf_len);
160 int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
161                           unsigned char *hash, unsigned int *hash_len);
162 int cfs_crypto_register(void);
163 void cfs_crypto_unregister(void);
164 int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg);
165 #endif