208 lines
5.2 KiB
C
208 lines
5.2 KiB
C
/* 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
|