• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
cfs_crypto_hash_type(unsigned char hash_alg)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" */
cfs_crypto_hash_name(unsigned char hash_alg)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 */
cfs_crypto_hash_digestsize(unsigned char hash_alg)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 */
cfs_crypto_hash_alg(const char * algname)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
200