linux/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h
<<
>>
Prefs
   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
  31struct 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
  39enum 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
  52static 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 */
  65static inline const struct cfs_crypto_hash_type *
  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" */
  79static 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 */
  90static 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 */
 101static 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 */
 129int 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 */
 135struct 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 */
 145struct 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 */
 157int 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 */
 168int 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 */
 183int 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 */
 188int cfs_crypto_register(void);
 189
 190/**
 191 *      Unregister
 192 */
 193void 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 */
 198int cfs_crypto_hash_speed(unsigned char hash_alg);
 199#endif
 200