0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <crypto/internal/cipher.h>
0010 #include <crypto/internal/hash.h>
0011 #include <linux/err.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014
0015 static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
0016 0x02020202, 0x02020202, 0x02020202, 0x02020202,
0017 0x03030303, 0x03030303, 0x03030303, 0x03030303};
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 struct xcbc_tfm_ctx {
0029 struct crypto_cipher *child;
0030 u8 ctx[];
0031 };
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 struct xcbc_desc_ctx {
0045 unsigned int len;
0046 u8 ctx[];
0047 };
0048
0049 #define XCBC_BLOCKSIZE 16
0050
0051 static int crypto_xcbc_digest_setkey(struct crypto_shash *parent,
0052 const u8 *inkey, unsigned int keylen)
0053 {
0054 unsigned long alignmask = crypto_shash_alignmask(parent);
0055 struct xcbc_tfm_ctx *ctx = crypto_shash_ctx(parent);
0056 u8 *consts = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
0057 int err = 0;
0058 u8 key1[XCBC_BLOCKSIZE];
0059 int bs = sizeof(key1);
0060
0061 if ((err = crypto_cipher_setkey(ctx->child, inkey, keylen)))
0062 return err;
0063
0064 crypto_cipher_encrypt_one(ctx->child, consts, (u8 *)ks + bs);
0065 crypto_cipher_encrypt_one(ctx->child, consts + bs, (u8 *)ks + bs * 2);
0066 crypto_cipher_encrypt_one(ctx->child, key1, (u8 *)ks);
0067
0068 return crypto_cipher_setkey(ctx->child, key1, bs);
0069
0070 }
0071
0072 static int crypto_xcbc_digest_init(struct shash_desc *pdesc)
0073 {
0074 unsigned long alignmask = crypto_shash_alignmask(pdesc->tfm);
0075 struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
0076 int bs = crypto_shash_blocksize(pdesc->tfm);
0077 u8 *prev = PTR_ALIGN(&ctx->ctx[0], alignmask + 1) + bs;
0078
0079 ctx->len = 0;
0080 memset(prev, 0, bs);
0081
0082 return 0;
0083 }
0084
0085 static int crypto_xcbc_digest_update(struct shash_desc *pdesc, const u8 *p,
0086 unsigned int len)
0087 {
0088 struct crypto_shash *parent = pdesc->tfm;
0089 unsigned long alignmask = crypto_shash_alignmask(parent);
0090 struct xcbc_tfm_ctx *tctx = crypto_shash_ctx(parent);
0091 struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
0092 struct crypto_cipher *tfm = tctx->child;
0093 int bs = crypto_shash_blocksize(parent);
0094 u8 *odds = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
0095 u8 *prev = odds + bs;
0096
0097
0098 if ((ctx->len + len) <= bs) {
0099 memcpy(odds + ctx->len, p, len);
0100 ctx->len += len;
0101 return 0;
0102 }
0103
0104
0105 memcpy(odds + ctx->len, p, bs - ctx->len);
0106 len -= bs - ctx->len;
0107 p += bs - ctx->len;
0108
0109 crypto_xor(prev, odds, bs);
0110 crypto_cipher_encrypt_one(tfm, prev, prev);
0111
0112
0113 ctx->len = 0;
0114
0115
0116 while (len > bs) {
0117 crypto_xor(prev, p, bs);
0118 crypto_cipher_encrypt_one(tfm, prev, prev);
0119 p += bs;
0120 len -= bs;
0121 }
0122
0123
0124 if (len) {
0125 memcpy(odds, p, len);
0126 ctx->len = len;
0127 }
0128
0129 return 0;
0130 }
0131
0132 static int crypto_xcbc_digest_final(struct shash_desc *pdesc, u8 *out)
0133 {
0134 struct crypto_shash *parent = pdesc->tfm;
0135 unsigned long alignmask = crypto_shash_alignmask(parent);
0136 struct xcbc_tfm_ctx *tctx = crypto_shash_ctx(parent);
0137 struct xcbc_desc_ctx *ctx = shash_desc_ctx(pdesc);
0138 struct crypto_cipher *tfm = tctx->child;
0139 int bs = crypto_shash_blocksize(parent);
0140 u8 *consts = PTR_ALIGN(&tctx->ctx[0], alignmask + 1);
0141 u8 *odds = PTR_ALIGN(&ctx->ctx[0], alignmask + 1);
0142 u8 *prev = odds + bs;
0143 unsigned int offset = 0;
0144
0145 if (ctx->len != bs) {
0146 unsigned int rlen;
0147 u8 *p = odds + ctx->len;
0148
0149 *p = 0x80;
0150 p++;
0151
0152 rlen = bs - ctx->len -1;
0153 if (rlen)
0154 memset(p, 0, rlen);
0155
0156 offset += bs;
0157 }
0158
0159 crypto_xor(prev, odds, bs);
0160 crypto_xor(prev, consts + offset, bs);
0161
0162 crypto_cipher_encrypt_one(tfm, out, prev);
0163
0164 return 0;
0165 }
0166
0167 static int xcbc_init_tfm(struct crypto_tfm *tfm)
0168 {
0169 struct crypto_cipher *cipher;
0170 struct crypto_instance *inst = (void *)tfm->__crt_alg;
0171 struct crypto_cipher_spawn *spawn = crypto_instance_ctx(inst);
0172 struct xcbc_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
0173
0174 cipher = crypto_spawn_cipher(spawn);
0175 if (IS_ERR(cipher))
0176 return PTR_ERR(cipher);
0177
0178 ctx->child = cipher;
0179
0180 return 0;
0181 };
0182
0183 static void xcbc_exit_tfm(struct crypto_tfm *tfm)
0184 {
0185 struct xcbc_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
0186 crypto_free_cipher(ctx->child);
0187 }
0188
0189 static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
0190 {
0191 struct shash_instance *inst;
0192 struct crypto_cipher_spawn *spawn;
0193 struct crypto_alg *alg;
0194 unsigned long alignmask;
0195 u32 mask;
0196 int err;
0197
0198 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
0199 if (err)
0200 return err;
0201
0202 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
0203 if (!inst)
0204 return -ENOMEM;
0205 spawn = shash_instance_ctx(inst);
0206
0207 err = crypto_grab_cipher(spawn, shash_crypto_instance(inst),
0208 crypto_attr_alg_name(tb[1]), 0, mask);
0209 if (err)
0210 goto err_free_inst;
0211 alg = crypto_spawn_cipher_alg(spawn);
0212
0213 err = -EINVAL;
0214 if (alg->cra_blocksize != XCBC_BLOCKSIZE)
0215 goto err_free_inst;
0216
0217 err = crypto_inst_setname(shash_crypto_instance(inst), tmpl->name, alg);
0218 if (err)
0219 goto err_free_inst;
0220
0221 alignmask = alg->cra_alignmask | 3;
0222 inst->alg.base.cra_alignmask = alignmask;
0223 inst->alg.base.cra_priority = alg->cra_priority;
0224 inst->alg.base.cra_blocksize = alg->cra_blocksize;
0225
0226 inst->alg.digestsize = alg->cra_blocksize;
0227 inst->alg.descsize = ALIGN(sizeof(struct xcbc_desc_ctx),
0228 crypto_tfm_ctx_alignment()) +
0229 (alignmask &
0230 ~(crypto_tfm_ctx_alignment() - 1)) +
0231 alg->cra_blocksize * 2;
0232
0233 inst->alg.base.cra_ctxsize = ALIGN(sizeof(struct xcbc_tfm_ctx),
0234 alignmask + 1) +
0235 alg->cra_blocksize * 2;
0236 inst->alg.base.cra_init = xcbc_init_tfm;
0237 inst->alg.base.cra_exit = xcbc_exit_tfm;
0238
0239 inst->alg.init = crypto_xcbc_digest_init;
0240 inst->alg.update = crypto_xcbc_digest_update;
0241 inst->alg.final = crypto_xcbc_digest_final;
0242 inst->alg.setkey = crypto_xcbc_digest_setkey;
0243
0244 inst->free = shash_free_singlespawn_instance;
0245
0246 err = shash_register_instance(tmpl, inst);
0247 if (err) {
0248 err_free_inst:
0249 shash_free_singlespawn_instance(inst);
0250 }
0251 return err;
0252 }
0253
0254 static struct crypto_template crypto_xcbc_tmpl = {
0255 .name = "xcbc",
0256 .create = xcbc_create,
0257 .module = THIS_MODULE,
0258 };
0259
0260 static int __init crypto_xcbc_module_init(void)
0261 {
0262 return crypto_register_template(&crypto_xcbc_tmpl);
0263 }
0264
0265 static void __exit crypto_xcbc_module_exit(void)
0266 {
0267 crypto_unregister_template(&crypto_xcbc_tmpl);
0268 }
0269
0270 subsys_initcall(crypto_xcbc_module_init);
0271 module_exit(crypto_xcbc_module_exit);
0272
0273 MODULE_LICENSE("GPL");
0274 MODULE_DESCRIPTION("XCBC keyed hash algorithm");
0275 MODULE_ALIAS_CRYPTO("xcbc");
0276 MODULE_IMPORT_NS(CRYPTO_INTERNAL);