linux/crypto/aead.c
<<
>>
Prefs
   1/*
   2 * AEAD: Authenticated Encryption with Associated Data
   3 * 
   4 * This file provides API support for AEAD algorithms.
   5 *
   6 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of the GNU General Public License as published by the Free
  10 * Software Foundation; either version 2 of the License, or (at your option) 
  11 * any later version.
  12 *
  13 */
  14
  15#include <crypto/algapi.h>
  16#include <linux/errno.h>
  17#include <linux/init.h>
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/slab.h>
  21#include <linux/seq_file.h>
  22
  23static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
  24                            unsigned int keylen)
  25{
  26        struct aead_alg *aead = crypto_aead_alg(tfm);
  27        unsigned long alignmask = crypto_aead_alignmask(tfm);
  28        int ret;
  29        u8 *buffer, *alignbuffer;
  30        unsigned long absize;
  31
  32        absize = keylen + alignmask;
  33        buffer = kmalloc(absize, GFP_ATOMIC);
  34        if (!buffer)
  35                return -ENOMEM;
  36
  37        alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
  38        memcpy(alignbuffer, key, keylen);
  39        ret = aead->setkey(tfm, alignbuffer, keylen);
  40        memset(alignbuffer, 0, keylen);
  41        kfree(buffer);
  42        return ret;
  43}
  44
  45static int setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
  46{
  47        struct aead_alg *aead = crypto_aead_alg(tfm);
  48        unsigned long alignmask = crypto_aead_alignmask(tfm);
  49
  50        if ((unsigned long)key & alignmask)
  51                return setkey_unaligned(tfm, key, keylen);
  52
  53        return aead->setkey(tfm, key, keylen);
  54}
  55
  56static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type,
  57                                        u32 mask)
  58{
  59        return alg->cra_ctxsize;
  60}
  61
  62static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
  63{
  64        struct aead_alg *alg = &tfm->__crt_alg->cra_aead;
  65        struct aead_tfm *crt = &tfm->crt_aead;
  66
  67        if (max(alg->authsize, alg->ivsize) > PAGE_SIZE / 8)
  68                return -EINVAL;
  69
  70        crt->setkey = setkey;
  71        crt->encrypt = alg->encrypt;
  72        crt->decrypt = alg->decrypt;
  73        crt->ivsize = alg->ivsize;
  74        crt->authsize = alg->authsize;
  75
  76        return 0;
  77}
  78
  79static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
  80        __attribute__ ((unused));
  81static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
  82{
  83        struct aead_alg *aead = &alg->cra_aead;
  84
  85        seq_printf(m, "type         : aead\n");
  86        seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
  87        seq_printf(m, "ivsize       : %u\n", aead->ivsize);
  88        seq_printf(m, "authsize     : %u\n", aead->authsize);
  89}
  90
  91const struct crypto_type crypto_aead_type = {
  92        .ctxsize = crypto_aead_ctxsize,
  93        .init = crypto_init_aead_ops,
  94#ifdef CONFIG_PROC_FS
  95        .show = crypto_aead_show,
  96#endif
  97};
  98EXPORT_SYMBOL_GPL(crypto_aead_type);
  99
 100MODULE_LICENSE("GPL");
 101MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)");
 102