/*
* Copyright 2012 Xyratex Technology Limited
+ *
+ * Copyright (c) 2014, Intel Corporation.
*/
#ifndef _LIBCFS_CRYPTO_H
unsigned int cht_size; /**< hash digest size */
};
+struct cfs_crypto_crypt_type {
+ char *cct_name; /**< crypto algorithm name, equal to
+ * format name for crypto api */
+ unsigned int cct_size; /**< crypto key size */
+};
+
enum cfs_crypto_hash_alg {
- CFS_HASH_ALG_NULL = 0,
+ CFS_HASH_ALG_NULL = 0,
CFS_HASH_ALG_ADLER32,
CFS_HASH_ALG_CRC32,
+ CFS_HASH_ALG_CRC32C,
+ /* hashes before here will be speed-tested at module load */
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_MAX,
+ CFS_HASH_ALG_SPEED_MAX = CFS_HASH_ALG_MD5,
+ CFS_HASH_ALG_UNKNOWN = 0xff
+};
+
+enum cfs_crypto_crypt_alg {
+ CFS_CRYPT_ALG_NULL = 0,
+ CFS_CRYPT_ALG_AES256_CTR,
+ CFS_CRYPT_ALG_MAX,
+ CFS_CRYPT_ALG_UNKNOWN = 0xff
};
static struct cfs_crypto_hash_type hash_types[] = {
- [CFS_HASH_ALG_NULL] = { "null", 0, 0 },
- [CFS_HASH_ALG_ADLER32] = { "adler32", 1, 4 },
- [CFS_HASH_ALG_CRC32] = { "crc32", ~0, 4 },
- [CFS_HASH_ALG_CRC32C] = { "crc32c", ~0, 4 },
- [CFS_HASH_ALG_MD5] = { "md5", 0, 16 },
- [CFS_HASH_ALG_SHA1] = { "sha1", 0, 20 },
- [CFS_HASH_ALG_SHA256] = { "sha256", 0, 32 },
- [CFS_HASH_ALG_SHA384] = { "sha384", 0, 48 },
- [CFS_HASH_ALG_SHA512] = { "sha512", 0, 64 },
+ [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
+ }
+};
+
+static struct cfs_crypto_crypt_type crypt_types[] = {
+ [CFS_CRYPT_ALG_NULL] = {
+ .cct_name = "null",
+ .cct_size = 0
+ },
+ [CFS_CRYPT_ALG_AES256_CTR] = {
+ .cct_name = "ctr(aes)",
+ .cct_size = 32
+ }
};
-/** Return pointer to type of hash for valid hash algorithm identifier */
-static inline const struct cfs_crypto_hash_type *
- cfs_crypto_hash_type(unsigned char hash_alg)
+/* 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)
+ if (ht->cht_name != NULL)
return ht;
}
return NULL;
}
-/** Return hash name for valid hash algorithm identifier or "unknown" */
-static inline const char *cfs_crypto_hash_name(unsigned char hash_alg)
+/**
+ * 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;
- else
- return "unknown";
+
+ return "unknown";
}
-/** Return digest size for valid algorithm identifier or 0 */
-static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg)
+/**
+ * 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
+unsigned 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)
+ if (ht != NULL)
return ht->cht_size;
- else
- return 0;
+
+ return 0;
}
-/** Return hash identifier for valid hash algorithm name or 0xFF */
+/**
+ * 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)
{
- unsigned char i;
+ 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) == 0)
+ return hash_alg;
- for (i = 0; i < CFS_HASH_ALG_MAX; i++)
- if (!strcmp(hash_types[i].cht_name, algname))
- break;
- return (i == CFS_HASH_ALG_MAX ? 0xFF : i);
+ return CFS_HASH_ALG_UNKNOWN;
}
-/** Calculate hash digest for buffer.
- * @param alg id of hash algorithm
- * @param buf buffer of data
- * @param buf_len buffer len
- * @param key initial value for algorithm, if it is NULL,
- * default initial value should be used.
- * @param key_len len of initial value
- * @param hash [out] pointer to hash, if it is NULL, hash_len is
- * set to valid digest size in bytes, retval -ENOSPC.
- * @param hash_len [in,out] size of hash buffer
- * @returns status of operation
- * @retval -EINVAL if buf, buf_len, hash_len or alg_id is invalid
- * @retval -ENODEV if this algorithm is unsupported
- * @retval -ENOSPC if pointer to hash is NULL, or hash_len less than
- * digest size
- * @retval 0 for success
- * @retval < 0 other errors from lower layers.
+/**
+ * Return crypt algorithm information for the specified algorithm identifier
+ *
+ * Crypt information includes algorithm name, key size.
+ *
+ * \retval cfs_crypto_crupt_type for valid ID (CFS_CRYPT_ALG_*)
+ * \retval NULL for unknown algorithm identifier
*/
-int cfs_crypto_hash_digest(unsigned char alg,
+static inline const struct
+cfs_crypto_crypt_type *cfs_crypto_crypt_type(
+ enum cfs_crypto_crypt_alg crypt_alg)
+{
+ struct cfs_crypto_crypt_type *ct;
+
+ if (crypt_alg < CFS_CRYPT_ALG_MAX) {
+ ct = &crypt_types[crypt_alg];
+ if (ct->cct_name != NULL)
+ return ct;
+ }
+ return NULL;
+}
+
+/**
+ * Return crypt name for crypt algorithm identifier
+ *
+ * \param[in] crypt_alg crypt alrgorithm id (CFS_CRYPT_ALG_*)
+ *
+ * \retval string name of known crypt algorithm
+ * \retval "unknown" if hash algorithm is unknown
+ */
+static inline const
+char *cfs_crypto_crypt_name(enum cfs_crypto_crypt_alg crypt_alg)
+{
+ const struct cfs_crypto_crypt_type *ct;
+
+ ct = cfs_crypto_crypt_type(crypt_alg);
+ if (ct)
+ return ct->cct_name;
+
+ return "unknown";
+}
+
+
+/**
+ * Return key size for crypto algorithm type
+ *
+ * \param[in] crypt_alg crypt alrgorithm id (CFS_CRYPT_ALG_*)
+ *
+ * \retval crypt algorithm key size in bytes
+ * \retval 0 if crypt algorithm type is unknown
+ */
+static inline
+unsigned int cfs_crypto_crypt_keysize(enum cfs_crypto_crypt_alg crypt_alg)
+{
+ const struct cfs_crypto_crypt_type *ct;
+
+ ct = cfs_crypto_crypt_type(crypt_alg);
+ if (ct != NULL)
+ return ct->cct_size;
+
+ return 0;
+}
+
+/**
+ * Find crypto algorithm ID for the specified algorithm name
+ *
+ * \retval crypto algorithm ID for valid ID (CFS_CRYPT_ALG_*)
+ * \retval CFS_CRYPT_ALG_UNKNOWN for unknown algorithm name
+ */
+static inline unsigned char cfs_crypto_crypt_alg(const char *algname)
+{
+ enum cfs_crypto_crypt_alg crypt_alg;
+
+ for (crypt_alg = 0; crypt_alg < CFS_CRYPT_ALG_MAX; crypt_alg++)
+ if (strcmp(crypt_types[crypt_alg].cct_name, algname) == 0)
+ return crypt_alg;
+
+ return CFS_CRYPT_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 page;
-/** Allocate and initialize desriptor for hash algorithm.
- * @param alg algorithm id
- * @param key initial value for algorithm, if it is NULL,
- * default initial value should be used.
- * @param key_len len of initial value
- * @returns pointer to descriptor of hash instance
- * @retval ERR_PTR(error) when errors occured.
- */
-struct cfs_crypto_hash_desc*
- cfs_crypto_hash_init(unsigned char alg,
+struct cfs_crypto_hash_desc *
+ cfs_crypto_hash_init(enum cfs_crypto_hash_alg hash_alg,
unsigned char *key, unsigned int key_len);
-
-/** Update digest by part of data.
- * @param desc hash descriptor
- * @param page data page
- * @param offset data offset
- * @param len data len
- * @returns status of operation
- * @retval 0 for success.
- */
int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
struct page *page, unsigned int offset,
unsigned int len);
-
-/** Update digest by part of data.
- * @param desc hash descriptor
- * @param buf pointer to data buffer
- * @param buf_len size of data at buffer
- * @returns status of operation
- * @retval 0 for success.
- */
int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
unsigned int buf_len);
-
-/** Finalize hash calculation, copy hash digest to buffer, destroy hash
- * descriptor.
- * @param desc hash descriptor
- * @param hash buffer pointer to store hash digest
- * @param hash_len pointer to hash buffer size, if NULL
- * destory hash descriptor
- * @returns status of operation
- * @retval -ENOSPC if hash is NULL, or *hash_len less than
- * digest size
- * @retval 0 for success
- * @retval < 0 other errors from lower layers.
- */
int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
unsigned char *hash, unsigned int *hash_len);
-/**
- * Register crypto hash algorithms
- */
int cfs_crypto_register(void);
-
-/**
- * Unregister
- */
void cfs_crypto_unregister(void);
-
-/** Return hash speed in Mbytes per second for valid hash algorithm
- * identifier. If test was unsuccessfull -1 would be return.
- */
-int cfs_crypto_hash_speed(unsigned char hash_alg);
+int cfs_crypto_hash_speed(enum cfs_crypto_hash_alg hash_alg);
#endif