[PATCH] md: new sysfs interface for setting bits in the write-intent-bitmap
[sfrench/cifs-2.6.git] / include / linux / crypto.h
index 0be666b5046322431e1639b4ca2fefdf6c0180eb..8f2ffa4caabfa1c0a425e54fa0c0185eb0fddf3d 100644 (file)
 #define CRYPTO_ALG_TYPE_MASK           0x0000000f
 #define CRYPTO_ALG_TYPE_CIPHER         0x00000001
 #define CRYPTO_ALG_TYPE_DIGEST         0x00000002
-#define CRYPTO_ALG_TYPE_BLKCIPHER      0x00000003
-#define CRYPTO_ALG_TYPE_COMPRESS       0x00000004
+#define CRYPTO_ALG_TYPE_HASH           0x00000003
+#define CRYPTO_ALG_TYPE_BLKCIPHER      0x00000004
+#define CRYPTO_ALG_TYPE_COMPRESS       0x00000005
+
+#define CRYPTO_ALG_TYPE_HASH_MASK      0x0000000e
 
 #define CRYPTO_ALG_LARVAL              0x00000010
 #define CRYPTO_ALG_DEAD                        0x00000020
 #define CRYPTO_ALG_DYING               0x00000040
 #define CRYPTO_ALG_ASYNC               0x00000080
 
+/*
+ * Set this bit if and only if the algorithm requires another algorithm of
+ * the same type to handle corner cases.
+ */
+#define CRYPTO_ALG_NEED_FALLBACK       0x00000100
+
 /*
  * Transform masks and values (for crt_flags).
  */
@@ -90,6 +99,7 @@
 
 struct scatterlist;
 struct crypto_blkcipher;
+struct crypto_hash;
 struct crypto_tfm;
 struct crypto_type;
 
@@ -107,6 +117,11 @@ struct cipher_desc {
        void *info;
 };
 
+struct hash_desc {
+       struct crypto_hash *tfm;
+       u32 flags;
+};
+
 /*
  * Algorithms: modular crypto algorithm implementations, managed
  * via crypto_register_alg() and crypto_unregister_alg().
@@ -158,6 +173,19 @@ struct digest_alg {
                          unsigned int keylen);
 };
 
+struct hash_alg {
+       int (*init)(struct hash_desc *desc);
+       int (*update)(struct hash_desc *desc, struct scatterlist *sg,
+                     unsigned int nbytes);
+       int (*final)(struct hash_desc *desc, u8 *out);
+       int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
+                     unsigned int nbytes, u8 *out);
+       int (*setkey)(struct crypto_hash *tfm, const u8 *key,
+                     unsigned int keylen);
+
+       unsigned int digestsize;
+};
+
 struct compress_alg {
        int (*coa_compress)(struct crypto_tfm *tfm, const u8 *src,
                            unsigned int slen, u8 *dst, unsigned int *dlen);
@@ -168,6 +196,7 @@ struct compress_alg {
 #define cra_blkcipher  cra_u.blkcipher
 #define cra_cipher     cra_u.cipher
 #define cra_digest     cra_u.digest
+#define cra_hash       cra_u.hash
 #define cra_compress   cra_u.compress
 
 struct crypto_alg {
@@ -191,6 +220,7 @@ struct crypto_alg {
                struct blkcipher_alg blkcipher;
                struct cipher_alg cipher;
                struct digest_alg digest;
+               struct hash_alg hash;
                struct compress_alg compress;
        } cra_u;
 
@@ -211,12 +241,21 @@ int crypto_unregister_alg(struct crypto_alg *alg);
  * Algorithm query interface.
  */
 #ifdef CONFIG_CRYPTO
-int crypto_alg_available(const char *name, u32 flags);
+int crypto_alg_available(const char *name, u32 flags)
+       __deprecated_for_modules;
+int crypto_has_alg(const char *name, u32 type, u32 mask);
 #else
+static int crypto_alg_available(const char *name, u32 flags);
+       __deprecated_for_modules;
 static inline int crypto_alg_available(const char *name, u32 flags)
 {
        return 0;
 }
+
+static inline int crypto_has_alg(const char *name, u32 type, u32 mask)
+{
+       return 0;
+}
 #endif
 
 /*
@@ -262,18 +301,16 @@ struct cipher_tfm {
        void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
 };
 
-struct digest_tfm {
-       void (*dit_init)(struct crypto_tfm *tfm);
-       void (*dit_update)(struct crypto_tfm *tfm,
-                          struct scatterlist *sg, unsigned int nsg);
-       void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
-       void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
-                          unsigned int nsg, u8 *out);
-       int (*dit_setkey)(struct crypto_tfm *tfm,
-                         const u8 *key, unsigned int keylen);
-#ifdef CONFIG_CRYPTO_HMAC
-       void *dit_hmac_block;
-#endif
+struct hash_tfm {
+       int (*init)(struct hash_desc *desc);
+       int (*update)(struct hash_desc *desc,
+                     struct scatterlist *sg, unsigned int nsg);
+       int (*final)(struct hash_desc *desc, u8 *out);
+       int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
+                     unsigned int nsg, u8 *out);
+       int (*setkey)(struct crypto_hash *tfm, const u8 *key,
+                     unsigned int keylen);
+       unsigned int digestsize;
 };
 
 struct compress_tfm {
@@ -287,7 +324,7 @@ struct compress_tfm {
 
 #define crt_blkcipher  crt_u.blkcipher
 #define crt_cipher     crt_u.cipher
-#define crt_digest     crt_u.digest
+#define crt_hash       crt_u.hash
 #define crt_compress   crt_u.compress
 
 struct crypto_tfm {
@@ -297,7 +334,7 @@ struct crypto_tfm {
        union {
                struct blkcipher_tfm blkcipher;
                struct cipher_tfm cipher;
-               struct digest_tfm digest;
+               struct hash_tfm hash;
                struct compress_tfm compress;
        } crt_u;
        
@@ -307,11 +344,16 @@ struct crypto_tfm {
 };
 
 #define crypto_cipher crypto_tfm
+#define crypto_comp crypto_tfm
 
 struct crypto_blkcipher {
        struct crypto_tfm base;
 };
 
+struct crypto_hash {
+       struct crypto_tfm base;
+};
+
 enum {
        CRYPTOA_UNSPEC,
        CRYPTOA_ALG,
@@ -459,6 +501,15 @@ static inline void crypto_free_blkcipher(struct crypto_blkcipher *tfm)
        crypto_free_tfm(crypto_blkcipher_tfm(tfm));
 }
 
+static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask)
+{
+       type &= ~CRYPTO_ALG_TYPE_MASK;
+       type |= CRYPTO_ALG_TYPE_BLKCIPHER;
+       mask |= CRYPTO_ALG_TYPE_MASK;
+
+       return crypto_has_alg(alg_name, type, mask);
+}
+
 static inline const char *crypto_blkcipher_name(struct crypto_blkcipher *tfm)
 {
        return crypto_tfm_alg_name(crypto_blkcipher_tfm(tfm));
@@ -594,6 +645,15 @@ static inline void crypto_free_cipher(struct crypto_cipher *tfm)
        crypto_free_tfm(crypto_cipher_tfm(tfm));
 }
 
+static inline int crypto_has_cipher(const char *alg_name, u32 type, u32 mask)
+{
+       type &= ~CRYPTO_ALG_TYPE_MASK;
+       type |= CRYPTO_ALG_TYPE_CIPHER;
+       mask |= CRYPTO_ALG_TYPE_MASK;
+
+       return crypto_has_alg(alg_name, type, mask);
+}
+
 static inline struct cipher_tfm *crypto_cipher_crt(struct crypto_cipher *tfm)
 {
        return &crypto_cipher_tfm(tfm)->crt_cipher;
@@ -647,39 +707,128 @@ static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,
                                                dst, src);
 }
 
-static inline void crypto_digest_init(struct crypto_tfm *tfm)
+void crypto_digest_init(struct crypto_tfm *tfm) __deprecated_for_modules;
+void crypto_digest_update(struct crypto_tfm *tfm,
+                         struct scatterlist *sg, unsigned int nsg)
+       __deprecated_for_modules;
+void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
+       __deprecated_for_modules;
+void crypto_digest_digest(struct crypto_tfm *tfm,
+                         struct scatterlist *sg, unsigned int nsg, u8 *out)
+       __deprecated_for_modules;
+
+static inline struct crypto_hash *__crypto_hash_cast(struct crypto_tfm *tfm)
 {
-       BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-       tfm->crt_digest.dit_init(tfm);
+       return (struct crypto_hash *)tfm;
 }
 
-static inline void crypto_digest_update(struct crypto_tfm *tfm,
-                                        struct scatterlist *sg,
-                                        unsigned int nsg)
+static inline struct crypto_hash *crypto_hash_cast(struct crypto_tfm *tfm)
 {
-       BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-       tfm->crt_digest.dit_update(tfm, sg, nsg);
+       BUG_ON((crypto_tfm_alg_type(tfm) ^ CRYPTO_ALG_TYPE_HASH) &
+              CRYPTO_ALG_TYPE_HASH_MASK);
+       return __crypto_hash_cast(tfm);
 }
 
-static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
+static int crypto_digest_setkey(struct crypto_tfm *tfm, const u8 *key,
+                               unsigned int keylen) __deprecated;
+static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
+                                       const u8 *key, unsigned int keylen)
 {
-       BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-       tfm->crt_digest.dit_final(tfm, out);
+       return tfm->crt_hash.setkey(crypto_hash_cast(tfm), key, keylen);
 }
 
-static inline void crypto_digest_digest(struct crypto_tfm *tfm,
-                                        struct scatterlist *sg,
-                                        unsigned int nsg, u8 *out)
+static inline struct crypto_hash *crypto_alloc_hash(const char *alg_name,
+                                                   u32 type, u32 mask)
 {
-       BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-       tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
+       type &= ~CRYPTO_ALG_TYPE_MASK;
+       type |= CRYPTO_ALG_TYPE_HASH;
+       mask |= CRYPTO_ALG_TYPE_HASH_MASK;
+
+       return __crypto_hash_cast(crypto_alloc_base(alg_name, type, mask));
 }
 
-static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
-                                       const u8 *key, unsigned int keylen)
+static inline struct crypto_tfm *crypto_hash_tfm(struct crypto_hash *tfm)
 {
-       BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-       return tfm->crt_digest.dit_setkey(tfm, key, keylen);
+       return &tfm->base;
+}
+
+static inline void crypto_free_hash(struct crypto_hash *tfm)
+{
+       crypto_free_tfm(crypto_hash_tfm(tfm));
+}
+
+static inline int crypto_has_hash(const char *alg_name, u32 type, u32 mask)
+{
+       type &= ~CRYPTO_ALG_TYPE_MASK;
+       type |= CRYPTO_ALG_TYPE_HASH;
+       mask |= CRYPTO_ALG_TYPE_HASH_MASK;
+
+       return crypto_has_alg(alg_name, type, mask);
+}
+
+static inline struct hash_tfm *crypto_hash_crt(struct crypto_hash *tfm)
+{
+       return &crypto_hash_tfm(tfm)->crt_hash;
+}
+
+static inline unsigned int crypto_hash_blocksize(struct crypto_hash *tfm)
+{
+       return crypto_tfm_alg_blocksize(crypto_hash_tfm(tfm));
+}
+
+static inline unsigned int crypto_hash_alignmask(struct crypto_hash *tfm)
+{
+       return crypto_tfm_alg_alignmask(crypto_hash_tfm(tfm));
+}
+
+static inline unsigned int crypto_hash_digestsize(struct crypto_hash *tfm)
+{
+       return crypto_hash_crt(tfm)->digestsize;
+}
+
+static inline u32 crypto_hash_get_flags(struct crypto_hash *tfm)
+{
+       return crypto_tfm_get_flags(crypto_hash_tfm(tfm));
+}
+
+static inline void crypto_hash_set_flags(struct crypto_hash *tfm, u32 flags)
+{
+       crypto_tfm_set_flags(crypto_hash_tfm(tfm), flags);
+}
+
+static inline void crypto_hash_clear_flags(struct crypto_hash *tfm, u32 flags)
+{
+       crypto_tfm_clear_flags(crypto_hash_tfm(tfm), flags);
+}
+
+static inline int crypto_hash_init(struct hash_desc *desc)
+{
+       return crypto_hash_crt(desc->tfm)->init(desc);
+}
+
+static inline int crypto_hash_update(struct hash_desc *desc,
+                                    struct scatterlist *sg,
+                                    unsigned int nbytes)
+{
+       return crypto_hash_crt(desc->tfm)->update(desc, sg, nbytes);
+}
+
+static inline int crypto_hash_final(struct hash_desc *desc, u8 *out)
+{
+       return crypto_hash_crt(desc->tfm)->final(desc, out);
+}
+
+static inline int crypto_hash_digest(struct hash_desc *desc,
+                                    struct scatterlist *sg,
+                                    unsigned int nbytes, u8 *out)
+{
+       return crypto_hash_crt(desc->tfm)->digest(desc, sg, nbytes, out);
+}
+
+static inline int crypto_hash_setkey(struct crypto_hash *hash,
+                                    const u8 *key, unsigned int keylen)
+{
+       return crypto_hash_crt(hash)->setkey(hash, key, keylen);
 }
 
 static int crypto_cipher_encrypt(struct crypto_tfm *tfm,
@@ -752,34 +901,70 @@ static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
        memcpy(dst, tfm->crt_cipher.cit_iv, len);
 }
 
-static inline int crypto_comp_compress(struct crypto_tfm *tfm,
+static inline struct crypto_comp *__crypto_comp_cast(struct crypto_tfm *tfm)
+{
+       return (struct crypto_comp *)tfm;
+}
+
+static inline struct crypto_comp *crypto_comp_cast(struct crypto_tfm *tfm)
+{
+       BUG_ON((crypto_tfm_alg_type(tfm) ^ CRYPTO_ALG_TYPE_COMPRESS) &
+              CRYPTO_ALG_TYPE_MASK);
+       return __crypto_comp_cast(tfm);
+}
+
+static inline struct crypto_comp *crypto_alloc_comp(const char *alg_name,
+                                                   u32 type, u32 mask)
+{
+       type &= ~CRYPTO_ALG_TYPE_MASK;
+       type |= CRYPTO_ALG_TYPE_COMPRESS;
+       mask |= CRYPTO_ALG_TYPE_MASK;
+
+       return __crypto_comp_cast(crypto_alloc_base(alg_name, type, mask));
+}
+
+static inline struct crypto_tfm *crypto_comp_tfm(struct crypto_comp *tfm)
+{
+       return tfm;
+}
+
+static inline void crypto_free_comp(struct crypto_comp *tfm)
+{
+       crypto_free_tfm(crypto_comp_tfm(tfm));
+}
+
+static inline int crypto_has_comp(const char *alg_name, u32 type, u32 mask)
+{
+       type &= ~CRYPTO_ALG_TYPE_MASK;
+       type |= CRYPTO_ALG_TYPE_COMPRESS;
+       mask |= CRYPTO_ALG_TYPE_MASK;
+
+       return crypto_has_alg(alg_name, type, mask);
+}
+
+static inline const char *crypto_comp_name(struct crypto_comp *tfm)
+{
+       return crypto_tfm_alg_name(crypto_comp_tfm(tfm));
+}
+
+static inline struct compress_tfm *crypto_comp_crt(struct crypto_comp *tfm)
+{
+       return &crypto_comp_tfm(tfm)->crt_compress;
+}
+
+static inline int crypto_comp_compress(struct crypto_comp *tfm,
                                        const u8 *src, unsigned int slen,
                                        u8 *dst, unsigned int *dlen)
 {
-       BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
-       return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
+       return crypto_comp_crt(tfm)->cot_compress(tfm, src, slen, dst, dlen);
 }
 
-static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
+static inline int crypto_comp_decompress(struct crypto_comp *tfm,
                                          const u8 *src, unsigned int slen,
                                          u8 *dst, unsigned int *dlen)
 {
-       BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
-       return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
+       return crypto_comp_crt(tfm)->cot_decompress(tfm, src, slen, dst, dlen);
 }
 
-/*
- * HMAC support.
- */
-#ifdef CONFIG_CRYPTO_HMAC
-void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
-void crypto_hmac_update(struct crypto_tfm *tfm,
-                        struct scatterlist *sg, unsigned int nsg);
-void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
-                       unsigned int *keylen, u8 *out);
-void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
-                 struct scatterlist *sg, unsigned int nsg, u8 *out);
-#endif /* CONFIG_CRYPTO_HMAC */
-
 #endif /* _LINUX_CRYPTO_H */