]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - include/linux/crypto.h
[CRYPTO] skcipher: Add givcrypt operations and givcipher type
[linux-2.6.git] / include / linux / crypto.h
index 357e8cfedc375674f27887f48c597cc2222e5287..3656a24ea7f00dff3473decfb8a33d363a3c4c2a 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Möller.
+ * and Nettle, by Niels Möller.
  * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
 #define CRYPTO_ALG_TYPE_DIGEST         0x00000002
 #define CRYPTO_ALG_TYPE_HASH           0x00000003
 #define CRYPTO_ALG_TYPE_BLKCIPHER      0x00000004
-#define CRYPTO_ALG_TYPE_COMPRESS       0x00000005
+#define CRYPTO_ALG_TYPE_ABLKCIPHER     0x00000005
+#define CRYPTO_ALG_TYPE_GIVCIPHER      0x00000006
+#define CRYPTO_ALG_TYPE_COMPRESS       0x00000008
+#define CRYPTO_ALG_TYPE_AEAD           0x00000009
 
 #define CRYPTO_ALG_TYPE_HASH_MASK      0x0000000e
+#define CRYPTO_ALG_TYPE_BLKCIPHER_MASK 0x0000000c
 
 #define CRYPTO_ALG_LARVAL              0x00000010
 #define CRYPTO_ALG_DEAD                        0x00000020
 struct scatterlist;
 struct crypto_ablkcipher;
 struct crypto_async_request;
+struct crypto_aead;
 struct crypto_blkcipher;
 struct crypto_hash;
-struct crypto_queue;
 struct crypto_tfm;
 struct crypto_type;
+struct skcipher_givcrypt_request;
 
 typedef void (*crypto_completion_t)(struct crypto_async_request *req, int err);
 
@@ -121,6 +126,32 @@ struct ablkcipher_request {
        void *__ctx[] CRYPTO_MINALIGN_ATTR;
 };
 
+/**
+ *     struct aead_request - AEAD request
+ *     @base: Common attributes for async crypto requests
+ *     @assoclen: Length in bytes of associated data for authentication
+ *     @cryptlen: Length of data to be encrypted or decrypted
+ *     @iv: Initialisation vector
+ *     @assoc: Associated data
+ *     @src: Source data
+ *     @dst: Destination data
+ *     @__ctx: Start of private context data
+ */
+struct aead_request {
+       struct crypto_async_request base;
+
+       unsigned int assoclen;
+       unsigned int cryptlen;
+
+       u8 *iv;
+
+       struct scatterlist *assoc;
+       struct scatterlist *src;
+       struct scatterlist *dst;
+
+       void *__ctx[] CRYPTO_MINALIGN_ATTR;
+};
+
 struct blkcipher_desc {
        struct crypto_blkcipher *tfm;
        void *info;
@@ -149,14 +180,25 @@ struct ablkcipher_alg {
                      unsigned int keylen);
        int (*encrypt)(struct ablkcipher_request *req);
        int (*decrypt)(struct ablkcipher_request *req);
-
-       struct crypto_queue *queue;
+       int (*givencrypt)(struct skcipher_givcrypt_request *req);
+       int (*givdecrypt)(struct skcipher_givcrypt_request *req);
 
        unsigned int min_keysize;
        unsigned int max_keysize;
        unsigned int ivsize;
 };
 
+struct aead_alg {
+       int (*setkey)(struct crypto_aead *tfm, const u8 *key,
+                     unsigned int keylen);
+       int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize);
+       int (*encrypt)(struct aead_request *req);
+       int (*decrypt)(struct aead_request *req);
+
+       unsigned int ivsize;
+       unsigned int maxauthsize;
+};
+
 struct blkcipher_alg {
        int (*setkey)(struct crypto_tfm *tfm, const u8 *key,
                      unsigned int keylen);
@@ -212,6 +254,7 @@ struct compress_alg {
 };
 
 #define cra_ablkcipher cra_u.ablkcipher
+#define cra_aead       cra_u.aead
 #define cra_blkcipher  cra_u.blkcipher
 #define cra_cipher     cra_u.cipher
 #define cra_digest     cra_u.digest
@@ -237,6 +280,7 @@ struct crypto_alg {
 
        union {
                struct ablkcipher_alg ablkcipher;
+               struct aead_alg aead;
                struct blkcipher_alg blkcipher;
                struct cipher_alg cipher;
                struct digest_alg digest;
@@ -280,10 +324,23 @@ struct ablkcipher_tfm {
                      unsigned int keylen);
        int (*encrypt)(struct ablkcipher_request *req);
        int (*decrypt)(struct ablkcipher_request *req);
+       int (*givencrypt)(struct skcipher_givcrypt_request *req);
+       int (*givdecrypt)(struct skcipher_givcrypt_request *req);
+
        unsigned int ivsize;
        unsigned int reqsize;
 };
 
+struct aead_tfm {
+       int (*setkey)(struct crypto_aead *tfm, const u8 *key,
+                     unsigned int keylen);
+       int (*encrypt)(struct aead_request *req);
+       int (*decrypt)(struct aead_request *req);
+       unsigned int ivsize;
+       unsigned int authsize;
+       unsigned int reqsize;
+};
+
 struct blkcipher_tfm {
        void *iv;
        int (*setkey)(struct crypto_tfm *tfm, const u8 *key,
@@ -323,6 +380,7 @@ struct compress_tfm {
 };
 
 #define crt_ablkcipher crt_u.ablkcipher
+#define crt_aead       crt_u.aead
 #define crt_blkcipher  crt_u.blkcipher
 #define crt_cipher     crt_u.cipher
 #define crt_hash       crt_u.hash
@@ -334,6 +392,7 @@ struct crypto_tfm {
        
        union {
                struct ablkcipher_tfm ablkcipher;
+               struct aead_tfm aead;
                struct blkcipher_tfm blkcipher;
                struct cipher_tfm cipher;
                struct hash_tfm hash;
@@ -349,6 +408,10 @@ struct crypto_ablkcipher {
        struct crypto_tfm base;
 };
 
+struct crypto_aead {
+       struct crypto_tfm base;
+};
+
 struct crypto_blkcipher {
        struct crypto_tfm base;
 };
@@ -369,11 +432,15 @@ enum {
        CRYPTOA_UNSPEC,
        CRYPTOA_ALG,
        CRYPTOA_TYPE,
+       CRYPTOA_U32,
        __CRYPTOA_MAX,
 };
 
 #define CRYPTOA_MAX (__CRYPTOA_MAX - 1)
 
+/* Maximum number of (rtattr) parameters for each template. */
+#define CRYPTO_MAX_ATTRS 32
+
 struct crypto_attr_alg {
        char name[CRYPTO_MAX_ALG_NAME];
 };
@@ -383,6 +450,10 @@ struct crypto_attr_type {
        u32 mask;
 };
 
+struct crypto_attr_u32 {
+       u32 num;
+};
+
 /* 
  * Transform user interface.
  */
@@ -464,15 +535,26 @@ static inline struct crypto_ablkcipher *__crypto_ablkcipher_cast(
        return (struct crypto_ablkcipher *)tfm;
 }
 
-static inline struct crypto_ablkcipher *crypto_alloc_ablkcipher(
-       const char *alg_name, u32 type, u32 mask)
+static inline u32 crypto_skcipher_type(u32 type)
 {
        type &= ~CRYPTO_ALG_TYPE_MASK;
        type |= CRYPTO_ALG_TYPE_BLKCIPHER;
-       mask |= CRYPTO_ALG_TYPE_MASK;
+       return type;
+}
+
+static inline u32 crypto_skcipher_mask(u32 mask)
+{
+       mask &= ~CRYPTO_ALG_TYPE_MASK;
+       mask |= CRYPTO_ALG_TYPE_BLKCIPHER_MASK;
+       return mask;
+}
 
+static inline struct crypto_ablkcipher *crypto_alloc_ablkcipher(
+       const char *alg_name, u32 type, u32 mask)
+{
        return __crypto_ablkcipher_cast(
-               crypto_alloc_base(alg_name, type, mask));
+               crypto_alloc_base(alg_name, crypto_skcipher_type(type),
+                                 crypto_skcipher_mask(mask)));
 }
 
 static inline struct crypto_tfm *crypto_ablkcipher_tfm(
@@ -489,11 +571,8 @@ static inline void crypto_free_ablkcipher(struct crypto_ablkcipher *tfm)
 static inline int crypto_has_ablkcipher(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);
+       return crypto_has_alg(alg_name, crypto_skcipher_type(type),
+                             crypto_skcipher_mask(mask));
 }
 
 static inline struct ablkcipher_tfm *crypto_ablkcipher_crt(
@@ -563,7 +642,8 @@ static inline int crypto_ablkcipher_decrypt(struct ablkcipher_request *req)
        return crt->decrypt(req);
 }
 
-static inline int crypto_ablkcipher_reqsize(struct crypto_ablkcipher *tfm)
+static inline unsigned int crypto_ablkcipher_reqsize(
+       struct crypto_ablkcipher *tfm)
 {
        return crypto_ablkcipher_crt(tfm)->reqsize;
 }
@@ -619,6 +699,152 @@ static inline void ablkcipher_request_set_crypt(
        req->info = iv;
 }
 
+static inline struct crypto_aead *__crypto_aead_cast(struct crypto_tfm *tfm)
+{
+       return (struct crypto_aead *)tfm;
+}
+
+static inline struct crypto_aead *crypto_alloc_aead(const char *alg_name,
+                                                   u32 type, u32 mask)
+{
+       type &= ~CRYPTO_ALG_TYPE_MASK;
+       type |= CRYPTO_ALG_TYPE_AEAD;
+       mask |= CRYPTO_ALG_TYPE_MASK;
+
+       return __crypto_aead_cast(crypto_alloc_base(alg_name, type, mask));
+}
+
+static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm)
+{
+       return &tfm->base;
+}
+
+static inline void crypto_free_aead(struct crypto_aead *tfm)
+{
+       crypto_free_tfm(crypto_aead_tfm(tfm));
+}
+
+static inline struct aead_tfm *crypto_aead_crt(struct crypto_aead *tfm)
+{
+       return &crypto_aead_tfm(tfm)->crt_aead;
+}
+
+static inline unsigned int crypto_aead_ivsize(struct crypto_aead *tfm)
+{
+       return crypto_aead_crt(tfm)->ivsize;
+}
+
+static inline unsigned int crypto_aead_authsize(struct crypto_aead *tfm)
+{
+       return crypto_aead_crt(tfm)->authsize;
+}
+
+static inline unsigned int crypto_aead_blocksize(struct crypto_aead *tfm)
+{
+       return crypto_tfm_alg_blocksize(crypto_aead_tfm(tfm));
+}
+
+static inline unsigned int crypto_aead_alignmask(struct crypto_aead *tfm)
+{
+       return crypto_tfm_alg_alignmask(crypto_aead_tfm(tfm));
+}
+
+static inline u32 crypto_aead_get_flags(struct crypto_aead *tfm)
+{
+       return crypto_tfm_get_flags(crypto_aead_tfm(tfm));
+}
+
+static inline void crypto_aead_set_flags(struct crypto_aead *tfm, u32 flags)
+{
+       crypto_tfm_set_flags(crypto_aead_tfm(tfm), flags);
+}
+
+static inline void crypto_aead_clear_flags(struct crypto_aead *tfm, u32 flags)
+{
+       crypto_tfm_clear_flags(crypto_aead_tfm(tfm), flags);
+}
+
+static inline int crypto_aead_setkey(struct crypto_aead *tfm, const u8 *key,
+                                    unsigned int keylen)
+{
+       return crypto_aead_crt(tfm)->setkey(tfm, key, keylen);
+}
+
+int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize);
+
+static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req)
+{
+       return __crypto_aead_cast(req->base.tfm);
+}
+
+static inline int crypto_aead_encrypt(struct aead_request *req)
+{
+       return crypto_aead_crt(crypto_aead_reqtfm(req))->encrypt(req);
+}
+
+static inline int crypto_aead_decrypt(struct aead_request *req)
+{
+       return crypto_aead_crt(crypto_aead_reqtfm(req))->decrypt(req);
+}
+
+static inline unsigned int crypto_aead_reqsize(struct crypto_aead *tfm)
+{
+       return crypto_aead_crt(tfm)->reqsize;
+}
+
+static inline void aead_request_set_tfm(struct aead_request *req,
+                                       struct crypto_aead *tfm)
+{
+       req->base.tfm = crypto_aead_tfm(tfm);
+}
+
+static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm,
+                                                     gfp_t gfp)
+{
+       struct aead_request *req;
+
+       req = kmalloc(sizeof(*req) + crypto_aead_reqsize(tfm), gfp);
+
+       if (likely(req))
+               aead_request_set_tfm(req, tfm);
+
+       return req;
+}
+
+static inline void aead_request_free(struct aead_request *req)
+{
+       kfree(req);
+}
+
+static inline void aead_request_set_callback(struct aead_request *req,
+                                            u32 flags,
+                                            crypto_completion_t complete,
+                                            void *data)
+{
+       req->base.complete = complete;
+       req->base.data = data;
+       req->base.flags = flags;
+}
+
+static inline void aead_request_set_crypt(struct aead_request *req,
+                                         struct scatterlist *src,
+                                         struct scatterlist *dst,
+                                         unsigned int cryptlen, u8 *iv)
+{
+       req->src = src;
+       req->dst = dst;
+       req->cryptlen = cryptlen;
+       req->iv = iv;
+}
+
+static inline void aead_request_set_assoc(struct aead_request *req,
+                                         struct scatterlist *assoc,
+                                         unsigned int assoclen)
+{
+       req->assoc = assoc;
+       req->assoclen = assoclen;
+}
+
 static inline struct crypto_blkcipher *__crypto_blkcipher_cast(
        struct crypto_tfm *tfm)
 {
@@ -635,9 +861,9 @@ static inline struct crypto_blkcipher *crypto_blkcipher_cast(
 static inline struct crypto_blkcipher *crypto_alloc_blkcipher(
        const char *alg_name, u32 type, u32 mask)
 {
-       type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
+       type &= ~CRYPTO_ALG_TYPE_MASK;
        type |= CRYPTO_ALG_TYPE_BLKCIPHER;
-       mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC;
+       mask |= CRYPTO_ALG_TYPE_MASK;
 
        return __crypto_blkcipher_cast(crypto_alloc_base(alg_name, type, mask));
 }
@@ -655,9 +881,9 @@ static inline void crypto_free_blkcipher(struct crypto_blkcipher *tfm)
 
 static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask)
 {
-       type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
+       type &= ~CRYPTO_ALG_TYPE_MASK;
        type |= CRYPTO_ALG_TYPE_BLKCIPHER;
-       mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC;
+       mask |= CRYPTO_ALG_TYPE_MASK;
 
        return crypto_has_alg(alg_name, type, mask);
 }
@@ -875,6 +1101,7 @@ static inline struct crypto_hash *crypto_alloc_hash(const char *alg_name,
                                                    u32 type, u32 mask)
 {
        type &= ~CRYPTO_ALG_TYPE_MASK;
+       mask &= ~CRYPTO_ALG_TYPE_MASK;
        type |= CRYPTO_ALG_TYPE_HASH;
        mask |= CRYPTO_ALG_TYPE_HASH_MASK;
 
@@ -894,6 +1121,7 @@ static inline void crypto_free_hash(struct crypto_hash *tfm)
 static inline int crypto_has_hash(const char *alg_name, u32 type, u32 mask)
 {
        type &= ~CRYPTO_ALG_TYPE_MASK;
+       mask &= ~CRYPTO_ALG_TYPE_MASK;
        type |= CRYPTO_ALG_TYPE_HASH;
        mask |= CRYPTO_ALG_TYPE_HASH_MASK;