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 23 static 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 45 static 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 56 static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type, 57 u32 mask) 58 { 59 return alg->cra_ctxsize; 60 } 61 62 static 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 79 static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 80 __attribute__ ((unused)); 81 static 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 91 const 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 }; 98 EXPORT_SYMBOL_GPL(crypto_aead_type); 99 100 MODULE_LICENSE("GPL"); 101 MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)"); 102