Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | /* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see http://www.gnu.org/licenses
*
* Please visit http://www.xyratex.com/contact if you need additional
* information or have any questions.
*
* GPL HEADER END
*/
/*
* Copyright 2012 Xyratex Technology Limited
*/
#ifndef _LIBCFS_CRYPTO_H
#define _LIBCFS_CRYPTO_H
struct cfs_crypto_hash_type {
char *cht_name; /*< hash algorithm name, equal to
* format name for crypto api
*/
unsigned int cht_key; /*< init key by default (valid for
* 4 bytes context like crc32, adler
*/
unsigned int cht_size; /**< hash digest size */
};
enum cfs_crypto_hash_alg {
CFS_HASH_ALG_NULL = 0,
CFS_HASH_ALG_ADLER32,
CFS_HASH_ALG_CRC32,
CFS_HASH_ALG_MD5,
CFS_HASH_ALG_SHA1,
CFS_HASH_ALG_SHA256,
CFS_HASH_ALG_SHA384,
CFS_HASH_ALG_SHA512,
CFS_HASH_ALG_CRC32C,
CFS_HASH_ALG_MAX,
CFS_HASH_ALG_UNKNOWN = 0xff
};
static struct cfs_crypto_hash_type hash_types[] = {
[CFS_HASH_ALG_NULL] = {
.cht_name = "null",
.cht_key = 0,
.cht_size = 0
},
[CFS_HASH_ALG_ADLER32] = {
.cht_name = "adler32",
.cht_key = 1,
.cht_size = 4
},
[CFS_HASH_ALG_CRC32] = {
.cht_name = "crc32",
.cht_key = ~0,
.cht_size = 4
},
[CFS_HASH_ALG_CRC32C] = {
.cht_name = "crc32c",
.cht_key = ~0,
.cht_size = 4
},
[CFS_HASH_ALG_MD5] = {
.cht_name = "md5",
.cht_key = 0,
.cht_size = 16
},
[CFS_HASH_ALG_SHA1] = {
.cht_name = "sha1",
.cht_key = 0,
.cht_size = 20
},
[CFS_HASH_ALG_SHA256] = {
.cht_name = "sha256",
.cht_key = 0,
.cht_size = 32
},
[CFS_HASH_ALG_SHA384] = {
.cht_name = "sha384",
.cht_key = 0,
.cht_size = 48
},
[CFS_HASH_ALG_SHA512] = {
.cht_name = "sha512",
.cht_key = 0,
.cht_size = 64
},
[CFS_HASH_ALG_MAX] = {
.cht_name = NULL,
.cht_key = 0,
.cht_size = 64
},
};
/* Maximum size of hash_types[].cht_size */
#define CFS_CRYPTO_HASH_DIGESTSIZE_MAX 64
/**
* Return hash algorithm information for the specified algorithm identifier
*
* Hash information includes algorithm name, initial seed, hash size.
*
* \retval cfs_crypto_hash_type for valid ID (CFS_HASH_ALG_*)
* \retval NULL for unknown algorithm identifier
*/
static inline const struct cfs_crypto_hash_type *
cfs_crypto_hash_type(enum cfs_crypto_hash_alg hash_alg)
{
struct cfs_crypto_hash_type *ht;
if (hash_alg < CFS_HASH_ALG_MAX) {
ht = &hash_types[hash_alg];
if (ht->cht_name)
return ht;
}
return NULL;
}
/**
* Return hash name for hash algorithm identifier
*
* \param[in] hash_alg hash alrgorithm id (CFS_HASH_ALG_*)
*
* \retval string name of known hash algorithm
* \retval "unknown" if hash algorithm is unknown
*/
static inline const char *
cfs_crypto_hash_name(enum cfs_crypto_hash_alg hash_alg)
{
const struct cfs_crypto_hash_type *ht;
ht = cfs_crypto_hash_type(hash_alg);
if (ht)
return ht->cht_name;
return "unknown";
}
/**
* Return digest size for hash algorithm type
*
* \param[in] hash_alg hash alrgorithm id (CFS_HASH_ALG_*)
*
* \retval hash algorithm digest size in bytes
* \retval 0 if hash algorithm type is unknown
*/
static inline int cfs_crypto_hash_digestsize(enum cfs_crypto_hash_alg hash_alg)
{
const struct cfs_crypto_hash_type *ht;
ht = cfs_crypto_hash_type(hash_alg);
if (ht)
return ht->cht_size;
return 0;
}
/**
* Find hash algorithm ID for the specified algorithm name
*
* \retval hash algorithm ID for valid ID (CFS_HASH_ALG_*)
* \retval CFS_HASH_ALG_UNKNOWN for unknown algorithm name
*/
static inline unsigned char cfs_crypto_hash_alg(const char *algname)
{
enum cfs_crypto_hash_alg hash_alg;
for (hash_alg = 0; hash_alg < CFS_HASH_ALG_MAX; hash_alg++)
if (!strcmp(hash_types[hash_alg].cht_name, algname))
return hash_alg;
return CFS_HASH_ALG_UNKNOWN;
}
int cfs_crypto_hash_digest(enum cfs_crypto_hash_alg hash_alg,
const void *buf, unsigned int buf_len,
unsigned char *key, unsigned int key_len,
unsigned char *hash, unsigned int *hash_len);
/* cfs crypto hash descriptor */
struct cfs_crypto_hash_desc;
struct cfs_crypto_hash_desc *
cfs_crypto_hash_init(enum cfs_crypto_hash_alg hash_alg,
unsigned char *key, unsigned int key_len);
int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
struct page *page, unsigned int offset,
unsigned int len);
int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
unsigned int buf_len);
int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
unsigned char *hash, unsigned int *hash_len);
int cfs_crypto_register(void);
void cfs_crypto_unregister(void);
int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg);
#endif
|