Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Cryptographic API.
0004  *
0005  * ARIA Cipher Algorithm.
0006  *
0007  * Documentation of ARIA can be found in RFC 5794.
0008  * Copyright (c) 2022 Taehee Yoo <ap420073@gmail.com>
0009  *
0010  * Information for ARIA
0011  *     http://210.104.33.10/ARIA/index-e.html (English)
0012  *     http://seed.kisa.or.kr/ (Korean)
0013  *
0014  * Public domain version is distributed above.
0015  */
0016 
0017 #include <crypto/aria.h>
0018 
0019 static void aria_set_encrypt_key(struct aria_ctx *ctx, const u8 *in_key,
0020                  unsigned int key_len)
0021 {
0022     const __be32 *key = (const __be32 *)in_key;
0023     u32 w0[4], w1[4], w2[4], w3[4];
0024     u32 reg0, reg1, reg2, reg3;
0025     const u32 *ck;
0026     int rkidx = 0;
0027 
0028     ck = &key_rc[(key_len - 16) / 8][0];
0029 
0030     w0[0] = be32_to_cpu(key[0]);
0031     w0[1] = be32_to_cpu(key[1]);
0032     w0[2] = be32_to_cpu(key[2]);
0033     w0[3] = be32_to_cpu(key[3]);
0034 
0035     reg0 = w0[0] ^ ck[0];
0036     reg1 = w0[1] ^ ck[1];
0037     reg2 = w0[2] ^ ck[2];
0038     reg3 = w0[3] ^ ck[3];
0039 
0040     aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
0041 
0042     if (key_len > 16) {
0043         w1[0] = be32_to_cpu(key[4]);
0044         w1[1] = be32_to_cpu(key[5]);
0045         if (key_len > 24) {
0046             w1[2] = be32_to_cpu(key[6]);
0047             w1[3] = be32_to_cpu(key[7]);
0048         } else {
0049             w1[2] = 0;
0050             w1[3] = 0;
0051         }
0052     } else {
0053         w1[0] = 0;
0054         w1[1] = 0;
0055         w1[2] = 0;
0056         w1[3] = 0;
0057     }
0058 
0059     w1[0] ^= reg0;
0060     w1[1] ^= reg1;
0061     w1[2] ^= reg2;
0062     w1[3] ^= reg3;
0063 
0064     reg0 = w1[0];
0065     reg1 = w1[1];
0066     reg2 = w1[2];
0067     reg3 = w1[3];
0068 
0069     reg0 ^= ck[4];
0070     reg1 ^= ck[5];
0071     reg2 ^= ck[6];
0072     reg3 ^= ck[7];
0073 
0074     aria_subst_diff_even(&reg0, &reg1, &reg2, &reg3);
0075 
0076     reg0 ^= w0[0];
0077     reg1 ^= w0[1];
0078     reg2 ^= w0[2];
0079     reg3 ^= w0[3];
0080 
0081     w2[0] = reg0;
0082     w2[1] = reg1;
0083     w2[2] = reg2;
0084     w2[3] = reg3;
0085 
0086     reg0 ^= ck[8];
0087     reg1 ^= ck[9];
0088     reg2 ^= ck[10];
0089     reg3 ^= ck[11];
0090 
0091     aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
0092 
0093     w3[0] = reg0 ^ w1[0];
0094     w3[1] = reg1 ^ w1[1];
0095     w3[2] = reg2 ^ w1[2];
0096     w3[3] = reg3 ^ w1[3];
0097 
0098     aria_gsrk(ctx->enc_key[rkidx], w0, w1, 19);
0099     rkidx++;
0100     aria_gsrk(ctx->enc_key[rkidx], w1, w2, 19);
0101     rkidx++;
0102     aria_gsrk(ctx->enc_key[rkidx], w2, w3, 19);
0103     rkidx++;
0104     aria_gsrk(ctx->enc_key[rkidx], w3, w0, 19);
0105 
0106     rkidx++;
0107     aria_gsrk(ctx->enc_key[rkidx], w0, w1, 31);
0108     rkidx++;
0109     aria_gsrk(ctx->enc_key[rkidx], w1, w2, 31);
0110     rkidx++;
0111     aria_gsrk(ctx->enc_key[rkidx], w2, w3, 31);
0112     rkidx++;
0113     aria_gsrk(ctx->enc_key[rkidx], w3, w0, 31);
0114 
0115     rkidx++;
0116     aria_gsrk(ctx->enc_key[rkidx], w0, w1, 67);
0117     rkidx++;
0118     aria_gsrk(ctx->enc_key[rkidx], w1, w2, 67);
0119     rkidx++;
0120     aria_gsrk(ctx->enc_key[rkidx], w2, w3, 67);
0121     rkidx++;
0122     aria_gsrk(ctx->enc_key[rkidx], w3, w0, 67);
0123 
0124     rkidx++;
0125     aria_gsrk(ctx->enc_key[rkidx], w0, w1, 97);
0126     if (key_len > 16) {
0127         rkidx++;
0128         aria_gsrk(ctx->enc_key[rkidx], w1, w2, 97);
0129         rkidx++;
0130         aria_gsrk(ctx->enc_key[rkidx], w2, w3, 97);
0131 
0132         if (key_len > 24) {
0133             rkidx++;
0134             aria_gsrk(ctx->enc_key[rkidx], w3, w0, 97);
0135 
0136             rkidx++;
0137             aria_gsrk(ctx->enc_key[rkidx], w0, w1, 109);
0138         }
0139     }
0140 }
0141 
0142 static void aria_set_decrypt_key(struct aria_ctx *ctx)
0143 {
0144     int i;
0145 
0146     for (i = 0; i < 4; i++) {
0147         ctx->dec_key[0][i] = ctx->enc_key[ctx->rounds][i];
0148         ctx->dec_key[ctx->rounds][i] = ctx->enc_key[0][i];
0149     }
0150 
0151     for (i = 1; i < ctx->rounds; i++) {
0152         ctx->dec_key[i][0] = aria_m(ctx->enc_key[ctx->rounds - i][0]);
0153         ctx->dec_key[i][1] = aria_m(ctx->enc_key[ctx->rounds - i][1]);
0154         ctx->dec_key[i][2] = aria_m(ctx->enc_key[ctx->rounds - i][2]);
0155         ctx->dec_key[i][3] = aria_m(ctx->enc_key[ctx->rounds - i][3]);
0156 
0157         aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1],
0158                    &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
0159         aria_diff_byte(&ctx->dec_key[i][1],
0160                    &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
0161         aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1],
0162                    &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
0163     }
0164 }
0165 
0166 static int aria_set_key(struct crypto_tfm *tfm, const u8 *in_key,
0167             unsigned int key_len)
0168 {
0169     struct aria_ctx *ctx = crypto_tfm_ctx(tfm);
0170 
0171     if (key_len != 16 && key_len != 24 && key_len != 32)
0172         return -EINVAL;
0173 
0174     ctx->key_length = key_len;
0175     ctx->rounds = (key_len + 32) / 4;
0176 
0177     aria_set_encrypt_key(ctx, in_key, key_len);
0178     aria_set_decrypt_key(ctx);
0179 
0180     return 0;
0181 }
0182 
0183 static void __aria_crypt(struct aria_ctx *ctx, u8 *out, const u8 *in,
0184              u32 key[][ARIA_RD_KEY_WORDS])
0185 {
0186     const __be32 *src = (const __be32 *)in;
0187     __be32 *dst = (__be32 *)out;
0188     u32 reg0, reg1, reg2, reg3;
0189     int rounds, rkidx = 0;
0190 
0191     rounds = ctx->rounds;
0192 
0193     reg0 = be32_to_cpu(src[0]);
0194     reg1 = be32_to_cpu(src[1]);
0195     reg2 = be32_to_cpu(src[2]);
0196     reg3 = be32_to_cpu(src[3]);
0197 
0198     aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
0199     rkidx++;
0200 
0201     aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
0202     aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
0203     rkidx++;
0204 
0205     while ((rounds -= 2) > 0) {
0206         aria_subst_diff_even(&reg0, &reg1, &reg2, &reg3);
0207         aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
0208         rkidx++;
0209 
0210         aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
0211         aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
0212         rkidx++;
0213     }
0214 
0215     reg0 = key[rkidx][0] ^ make_u32((u8)(x1[get_u8(reg0, 0)]),
0216                     (u8)(x2[get_u8(reg0, 1)] >> 8),
0217                     (u8)(s1[get_u8(reg0, 2)]),
0218                     (u8)(s2[get_u8(reg0, 3)]));
0219     reg1 = key[rkidx][1] ^ make_u32((u8)(x1[get_u8(reg1, 0)]),
0220                     (u8)(x2[get_u8(reg1, 1)] >> 8),
0221                     (u8)(s1[get_u8(reg1, 2)]),
0222                     (u8)(s2[get_u8(reg1, 3)]));
0223     reg2 = key[rkidx][2] ^ make_u32((u8)(x1[get_u8(reg2, 0)]),
0224                     (u8)(x2[get_u8(reg2, 1)] >> 8),
0225                     (u8)(s1[get_u8(reg2, 2)]),
0226                     (u8)(s2[get_u8(reg2, 3)]));
0227     reg3 = key[rkidx][3] ^ make_u32((u8)(x1[get_u8(reg3, 0)]),
0228                     (u8)(x2[get_u8(reg3, 1)] >> 8),
0229                     (u8)(s1[get_u8(reg3, 2)]),
0230                     (u8)(s2[get_u8(reg3, 3)]));
0231 
0232     dst[0] = cpu_to_be32(reg0);
0233     dst[1] = cpu_to_be32(reg1);
0234     dst[2] = cpu_to_be32(reg2);
0235     dst[3] = cpu_to_be32(reg3);
0236 }
0237 
0238 static void aria_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
0239 {
0240     struct aria_ctx *ctx = crypto_tfm_ctx(tfm);
0241 
0242     __aria_crypt(ctx, out, in, ctx->enc_key);
0243 }
0244 
0245 static void aria_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
0246 {
0247     struct aria_ctx *ctx = crypto_tfm_ctx(tfm);
0248 
0249     __aria_crypt(ctx, out, in, ctx->dec_key);
0250 }
0251 
0252 static struct crypto_alg aria_alg = {
0253     .cra_name       =   "aria",
0254     .cra_driver_name    =   "aria-generic",
0255     .cra_priority       =   100,
0256     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
0257     .cra_blocksize      =   ARIA_BLOCK_SIZE,
0258     .cra_ctxsize        =   sizeof(struct aria_ctx),
0259     .cra_alignmask      =   3,
0260     .cra_module     =   THIS_MODULE,
0261     .cra_u          =   {
0262         .cipher = {
0263             .cia_min_keysize    =   ARIA_MIN_KEY_SIZE,
0264             .cia_max_keysize    =   ARIA_MAX_KEY_SIZE,
0265             .cia_setkey     =   aria_set_key,
0266             .cia_encrypt        =   aria_encrypt,
0267             .cia_decrypt        =   aria_decrypt
0268         }
0269     }
0270 };
0271 
0272 static int __init aria_init(void)
0273 {
0274     return crypto_register_alg(&aria_alg);
0275 }
0276 
0277 static void __exit aria_fini(void)
0278 {
0279     crypto_unregister_alg(&aria_alg);
0280 }
0281 
0282 subsys_initcall(aria_init);
0283 module_exit(aria_fini);
0284 
0285 MODULE_DESCRIPTION("ARIA Cipher Algorithm");
0286 MODULE_LICENSE("GPL");
0287 MODULE_AUTHOR("Taehee Yoo <ap420073@gmail.com>");
0288 MODULE_ALIAS_CRYPTO("aria");