1*a9b0838dSTaehee Yoo // SPDX-License-Identifier: GPL-2.0-or-later 2*a9b0838dSTaehee Yoo /* 3*a9b0838dSTaehee Yoo * Cryptographic API. 4*a9b0838dSTaehee Yoo * 5*a9b0838dSTaehee Yoo * ARIA Cipher Algorithm. 6*a9b0838dSTaehee Yoo * 7*a9b0838dSTaehee Yoo * Documentation of ARIA can be found in RFC 5794. 8*a9b0838dSTaehee Yoo * Copyright (c) 2022 Taehee Yoo <ap420073@gmail.com> 9*a9b0838dSTaehee Yoo * 10*a9b0838dSTaehee Yoo * Information for ARIA 11*a9b0838dSTaehee Yoo * http://210.104.33.10/ARIA/index-e.html (English) 12*a9b0838dSTaehee Yoo * http://seed.kisa.or.kr/ (Korean) 13*a9b0838dSTaehee Yoo * 14*a9b0838dSTaehee Yoo * Public domain version is distributed above. 15*a9b0838dSTaehee Yoo */ 16*a9b0838dSTaehee Yoo 17*a9b0838dSTaehee Yoo #include <crypto/aria.h> 18*a9b0838dSTaehee Yoo 19*a9b0838dSTaehee Yoo static const u32 key_rc[20] = { 20*a9b0838dSTaehee Yoo 0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0, 21*a9b0838dSTaehee Yoo 0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0, 22*a9b0838dSTaehee Yoo 0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e, 23*a9b0838dSTaehee Yoo 0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0, 24*a9b0838dSTaehee Yoo 0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0 25*a9b0838dSTaehee Yoo }; 26*a9b0838dSTaehee Yoo 27*a9b0838dSTaehee Yoo static void aria_set_encrypt_key(struct aria_ctx *ctx, const u8 *in_key, 28*a9b0838dSTaehee Yoo unsigned int key_len) 29*a9b0838dSTaehee Yoo { 30*a9b0838dSTaehee Yoo const __be32 *key = (const __be32 *)in_key; 31*a9b0838dSTaehee Yoo u32 w0[4], w1[4], w2[4], w3[4]; 32*a9b0838dSTaehee Yoo u32 reg0, reg1, reg2, reg3; 33*a9b0838dSTaehee Yoo const u32 *ck; 34*a9b0838dSTaehee Yoo int rkidx = 0; 35*a9b0838dSTaehee Yoo 36*a9b0838dSTaehee Yoo ck = &key_rc[(key_len - 16) / 2]; 37*a9b0838dSTaehee Yoo 38*a9b0838dSTaehee Yoo w0[0] = be32_to_cpu(key[0]); 39*a9b0838dSTaehee Yoo w0[1] = be32_to_cpu(key[1]); 40*a9b0838dSTaehee Yoo w0[2] = be32_to_cpu(key[2]); 41*a9b0838dSTaehee Yoo w0[3] = be32_to_cpu(key[3]); 42*a9b0838dSTaehee Yoo 43*a9b0838dSTaehee Yoo reg0 = w0[0] ^ ck[0]; 44*a9b0838dSTaehee Yoo reg1 = w0[1] ^ ck[1]; 45*a9b0838dSTaehee Yoo reg2 = w0[2] ^ ck[2]; 46*a9b0838dSTaehee Yoo reg3 = w0[3] ^ ck[3]; 47*a9b0838dSTaehee Yoo 48*a9b0838dSTaehee Yoo aria_subst_diff_odd(®0, ®1, ®2, ®3); 49*a9b0838dSTaehee Yoo 50*a9b0838dSTaehee Yoo if (key_len > 16) { 51*a9b0838dSTaehee Yoo w1[0] = be32_to_cpu(key[4]); 52*a9b0838dSTaehee Yoo w1[1] = be32_to_cpu(key[5]); 53*a9b0838dSTaehee Yoo if (key_len > 24) { 54*a9b0838dSTaehee Yoo w1[2] = be32_to_cpu(key[6]); 55*a9b0838dSTaehee Yoo w1[3] = be32_to_cpu(key[7]); 56*a9b0838dSTaehee Yoo } else { 57*a9b0838dSTaehee Yoo w1[2] = 0; 58*a9b0838dSTaehee Yoo w1[3] = 0; 59*a9b0838dSTaehee Yoo } 60*a9b0838dSTaehee Yoo } else { 61*a9b0838dSTaehee Yoo w1[0] = 0; 62*a9b0838dSTaehee Yoo w1[1] = 0; 63*a9b0838dSTaehee Yoo w1[2] = 0; 64*a9b0838dSTaehee Yoo w1[3] = 0; 65*a9b0838dSTaehee Yoo } 66*a9b0838dSTaehee Yoo 67*a9b0838dSTaehee Yoo w1[0] ^= reg0; 68*a9b0838dSTaehee Yoo w1[1] ^= reg1; 69*a9b0838dSTaehee Yoo w1[2] ^= reg2; 70*a9b0838dSTaehee Yoo w1[3] ^= reg3; 71*a9b0838dSTaehee Yoo 72*a9b0838dSTaehee Yoo reg0 = w1[0]; 73*a9b0838dSTaehee Yoo reg1 = w1[1]; 74*a9b0838dSTaehee Yoo reg2 = w1[2]; 75*a9b0838dSTaehee Yoo reg3 = w1[3]; 76*a9b0838dSTaehee Yoo 77*a9b0838dSTaehee Yoo reg0 ^= ck[4]; 78*a9b0838dSTaehee Yoo reg1 ^= ck[5]; 79*a9b0838dSTaehee Yoo reg2 ^= ck[6]; 80*a9b0838dSTaehee Yoo reg3 ^= ck[7]; 81*a9b0838dSTaehee Yoo 82*a9b0838dSTaehee Yoo aria_subst_diff_even(®0, ®1, ®2, ®3); 83*a9b0838dSTaehee Yoo 84*a9b0838dSTaehee Yoo reg0 ^= w0[0]; 85*a9b0838dSTaehee Yoo reg1 ^= w0[1]; 86*a9b0838dSTaehee Yoo reg2 ^= w0[2]; 87*a9b0838dSTaehee Yoo reg3 ^= w0[3]; 88*a9b0838dSTaehee Yoo 89*a9b0838dSTaehee Yoo w2[0] = reg0; 90*a9b0838dSTaehee Yoo w2[1] = reg1; 91*a9b0838dSTaehee Yoo w2[2] = reg2; 92*a9b0838dSTaehee Yoo w2[3] = reg3; 93*a9b0838dSTaehee Yoo 94*a9b0838dSTaehee Yoo reg0 ^= ck[8]; 95*a9b0838dSTaehee Yoo reg1 ^= ck[9]; 96*a9b0838dSTaehee Yoo reg2 ^= ck[10]; 97*a9b0838dSTaehee Yoo reg3 ^= ck[11]; 98*a9b0838dSTaehee Yoo 99*a9b0838dSTaehee Yoo aria_subst_diff_odd(®0, ®1, ®2, ®3); 100*a9b0838dSTaehee Yoo 101*a9b0838dSTaehee Yoo w3[0] = reg0 ^ w1[0]; 102*a9b0838dSTaehee Yoo w3[1] = reg1 ^ w1[1]; 103*a9b0838dSTaehee Yoo w3[2] = reg2 ^ w1[2]; 104*a9b0838dSTaehee Yoo w3[3] = reg3 ^ w1[3]; 105*a9b0838dSTaehee Yoo 106*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w0, w1, 19); 107*a9b0838dSTaehee Yoo rkidx++; 108*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w1, w2, 19); 109*a9b0838dSTaehee Yoo rkidx++; 110*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w2, w3, 19); 111*a9b0838dSTaehee Yoo rkidx++; 112*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w3, w0, 19); 113*a9b0838dSTaehee Yoo 114*a9b0838dSTaehee Yoo rkidx++; 115*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w0, w1, 31); 116*a9b0838dSTaehee Yoo rkidx++; 117*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w1, w2, 31); 118*a9b0838dSTaehee Yoo rkidx++; 119*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w2, w3, 31); 120*a9b0838dSTaehee Yoo rkidx++; 121*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w3, w0, 31); 122*a9b0838dSTaehee Yoo 123*a9b0838dSTaehee Yoo rkidx++; 124*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w0, w1, 67); 125*a9b0838dSTaehee Yoo rkidx++; 126*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w1, w2, 67); 127*a9b0838dSTaehee Yoo rkidx++; 128*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w2, w3, 67); 129*a9b0838dSTaehee Yoo rkidx++; 130*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w3, w0, 67); 131*a9b0838dSTaehee Yoo 132*a9b0838dSTaehee Yoo rkidx++; 133*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w0, w1, 97); 134*a9b0838dSTaehee Yoo if (key_len > 16) { 135*a9b0838dSTaehee Yoo rkidx++; 136*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w1, w2, 97); 137*a9b0838dSTaehee Yoo rkidx++; 138*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w2, w3, 97); 139*a9b0838dSTaehee Yoo 140*a9b0838dSTaehee Yoo if (key_len > 24) { 141*a9b0838dSTaehee Yoo rkidx++; 142*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w3, w0, 97); 143*a9b0838dSTaehee Yoo 144*a9b0838dSTaehee Yoo rkidx++; 145*a9b0838dSTaehee Yoo aria_gsrk(ctx->enc_key[rkidx], w0, w1, 109); 146*a9b0838dSTaehee Yoo } 147*a9b0838dSTaehee Yoo } 148*a9b0838dSTaehee Yoo } 149*a9b0838dSTaehee Yoo 150*a9b0838dSTaehee Yoo static void aria_set_decrypt_key(struct aria_ctx *ctx) 151*a9b0838dSTaehee Yoo { 152*a9b0838dSTaehee Yoo int i; 153*a9b0838dSTaehee Yoo 154*a9b0838dSTaehee Yoo for (i = 0; i < 4; i++) { 155*a9b0838dSTaehee Yoo ctx->dec_key[0][i] = ctx->enc_key[ctx->rounds][i]; 156*a9b0838dSTaehee Yoo ctx->dec_key[ctx->rounds][i] = ctx->enc_key[0][i]; 157*a9b0838dSTaehee Yoo } 158*a9b0838dSTaehee Yoo 159*a9b0838dSTaehee Yoo for (i = 1; i < ctx->rounds; i++) { 160*a9b0838dSTaehee Yoo ctx->dec_key[i][0] = aria_m(ctx->enc_key[ctx->rounds - i][0]); 161*a9b0838dSTaehee Yoo ctx->dec_key[i][1] = aria_m(ctx->enc_key[ctx->rounds - i][1]); 162*a9b0838dSTaehee Yoo ctx->dec_key[i][2] = aria_m(ctx->enc_key[ctx->rounds - i][2]); 163*a9b0838dSTaehee Yoo ctx->dec_key[i][3] = aria_m(ctx->enc_key[ctx->rounds - i][3]); 164*a9b0838dSTaehee Yoo 165*a9b0838dSTaehee Yoo aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1], 166*a9b0838dSTaehee Yoo &ctx->dec_key[i][2], &ctx->dec_key[i][3]); 167*a9b0838dSTaehee Yoo aria_diff_byte(&ctx->dec_key[i][1], 168*a9b0838dSTaehee Yoo &ctx->dec_key[i][2], &ctx->dec_key[i][3]); 169*a9b0838dSTaehee Yoo aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1], 170*a9b0838dSTaehee Yoo &ctx->dec_key[i][2], &ctx->dec_key[i][3]); 171*a9b0838dSTaehee Yoo } 172*a9b0838dSTaehee Yoo } 173*a9b0838dSTaehee Yoo 174*a9b0838dSTaehee Yoo int aria_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len) 175*a9b0838dSTaehee Yoo { 176*a9b0838dSTaehee Yoo struct aria_ctx *ctx = crypto_tfm_ctx(tfm); 177*a9b0838dSTaehee Yoo 178*a9b0838dSTaehee Yoo if (key_len != 16 && key_len != 24 && key_len != 32) 179*a9b0838dSTaehee Yoo return -EINVAL; 180*a9b0838dSTaehee Yoo 181*a9b0838dSTaehee Yoo ctx->key_length = key_len; 182*a9b0838dSTaehee Yoo ctx->rounds = (key_len + 32) / 4; 183*a9b0838dSTaehee Yoo 184*a9b0838dSTaehee Yoo aria_set_encrypt_key(ctx, in_key, key_len); 185*a9b0838dSTaehee Yoo aria_set_decrypt_key(ctx); 186*a9b0838dSTaehee Yoo 187*a9b0838dSTaehee Yoo return 0; 188*a9b0838dSTaehee Yoo } 189*a9b0838dSTaehee Yoo EXPORT_SYMBOL_GPL(aria_set_key); 190*a9b0838dSTaehee Yoo 191*a9b0838dSTaehee Yoo static void __aria_crypt(struct aria_ctx *ctx, u8 *out, const u8 *in, 192*a9b0838dSTaehee Yoo u32 key[][ARIA_RD_KEY_WORDS]) 193*a9b0838dSTaehee Yoo { 194*a9b0838dSTaehee Yoo const __be32 *src = (const __be32 *)in; 195*a9b0838dSTaehee Yoo __be32 *dst = (__be32 *)out; 196*a9b0838dSTaehee Yoo u32 reg0, reg1, reg2, reg3; 197*a9b0838dSTaehee Yoo int rounds, rkidx = 0; 198*a9b0838dSTaehee Yoo 199*a9b0838dSTaehee Yoo rounds = ctx->rounds; 200*a9b0838dSTaehee Yoo 201*a9b0838dSTaehee Yoo reg0 = be32_to_cpu(src[0]); 202*a9b0838dSTaehee Yoo reg1 = be32_to_cpu(src[1]); 203*a9b0838dSTaehee Yoo reg2 = be32_to_cpu(src[2]); 204*a9b0838dSTaehee Yoo reg3 = be32_to_cpu(src[3]); 205*a9b0838dSTaehee Yoo 206*a9b0838dSTaehee Yoo aria_add_round_key(key[rkidx], ®0, ®1, ®2, ®3); 207*a9b0838dSTaehee Yoo rkidx++; 208*a9b0838dSTaehee Yoo 209*a9b0838dSTaehee Yoo aria_subst_diff_odd(®0, ®1, ®2, ®3); 210*a9b0838dSTaehee Yoo aria_add_round_key(key[rkidx], ®0, ®1, ®2, ®3); 211*a9b0838dSTaehee Yoo rkidx++; 212*a9b0838dSTaehee Yoo 213*a9b0838dSTaehee Yoo while ((rounds -= 2) > 0) { 214*a9b0838dSTaehee Yoo aria_subst_diff_even(®0, ®1, ®2, ®3); 215*a9b0838dSTaehee Yoo aria_add_round_key(key[rkidx], ®0, ®1, ®2, ®3); 216*a9b0838dSTaehee Yoo rkidx++; 217*a9b0838dSTaehee Yoo 218*a9b0838dSTaehee Yoo aria_subst_diff_odd(®0, ®1, ®2, ®3); 219*a9b0838dSTaehee Yoo aria_add_round_key(key[rkidx], ®0, ®1, ®2, ®3); 220*a9b0838dSTaehee Yoo rkidx++; 221*a9b0838dSTaehee Yoo } 222*a9b0838dSTaehee Yoo 223*a9b0838dSTaehee Yoo reg0 = key[rkidx][0] ^ make_u32((u8)(x1[get_u8(reg0, 0)]), 224*a9b0838dSTaehee Yoo (u8)(x2[get_u8(reg0, 1)] >> 8), 225*a9b0838dSTaehee Yoo (u8)(s1[get_u8(reg0, 2)]), 226*a9b0838dSTaehee Yoo (u8)(s2[get_u8(reg0, 3)])); 227*a9b0838dSTaehee Yoo reg1 = key[rkidx][1] ^ make_u32((u8)(x1[get_u8(reg1, 0)]), 228*a9b0838dSTaehee Yoo (u8)(x2[get_u8(reg1, 1)] >> 8), 229*a9b0838dSTaehee Yoo (u8)(s1[get_u8(reg1, 2)]), 230*a9b0838dSTaehee Yoo (u8)(s2[get_u8(reg1, 3)])); 231*a9b0838dSTaehee Yoo reg2 = key[rkidx][2] ^ make_u32((u8)(x1[get_u8(reg2, 0)]), 232*a9b0838dSTaehee Yoo (u8)(x2[get_u8(reg2, 1)] >> 8), 233*a9b0838dSTaehee Yoo (u8)(s1[get_u8(reg2, 2)]), 234*a9b0838dSTaehee Yoo (u8)(s2[get_u8(reg2, 3)])); 235*a9b0838dSTaehee Yoo reg3 = key[rkidx][3] ^ make_u32((u8)(x1[get_u8(reg3, 0)]), 236*a9b0838dSTaehee Yoo (u8)(x2[get_u8(reg3, 1)] >> 8), 237*a9b0838dSTaehee Yoo (u8)(s1[get_u8(reg3, 2)]), 238*a9b0838dSTaehee Yoo (u8)(s2[get_u8(reg3, 3)])); 239*a9b0838dSTaehee Yoo 240*a9b0838dSTaehee Yoo dst[0] = cpu_to_be32(reg0); 241*a9b0838dSTaehee Yoo dst[1] = cpu_to_be32(reg1); 242*a9b0838dSTaehee Yoo dst[2] = cpu_to_be32(reg2); 243*a9b0838dSTaehee Yoo dst[3] = cpu_to_be32(reg3); 244*a9b0838dSTaehee Yoo } 245*a9b0838dSTaehee Yoo 246*a9b0838dSTaehee Yoo void aria_encrypt(void *_ctx, u8 *out, const u8 *in) 247*a9b0838dSTaehee Yoo { 248*a9b0838dSTaehee Yoo struct aria_ctx *ctx = (struct aria_ctx *)_ctx; 249*a9b0838dSTaehee Yoo 250*a9b0838dSTaehee Yoo __aria_crypt(ctx, out, in, ctx->enc_key); 251*a9b0838dSTaehee Yoo } 252*a9b0838dSTaehee Yoo EXPORT_SYMBOL_GPL(aria_encrypt); 253*a9b0838dSTaehee Yoo 254*a9b0838dSTaehee Yoo void aria_decrypt(void *_ctx, u8 *out, const u8 *in) 255*a9b0838dSTaehee Yoo { 256*a9b0838dSTaehee Yoo struct aria_ctx *ctx = (struct aria_ctx *)_ctx; 257*a9b0838dSTaehee Yoo 258*a9b0838dSTaehee Yoo __aria_crypt(ctx, out, in, ctx->dec_key); 259*a9b0838dSTaehee Yoo } 260*a9b0838dSTaehee Yoo EXPORT_SYMBOL_GPL(aria_decrypt); 261*a9b0838dSTaehee Yoo 262*a9b0838dSTaehee Yoo static void __aria_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 263*a9b0838dSTaehee Yoo { 264*a9b0838dSTaehee Yoo struct aria_ctx *ctx = crypto_tfm_ctx(tfm); 265*a9b0838dSTaehee Yoo 266*a9b0838dSTaehee Yoo __aria_crypt(ctx, out, in, ctx->enc_key); 267*a9b0838dSTaehee Yoo } 268*a9b0838dSTaehee Yoo 269*a9b0838dSTaehee Yoo static void __aria_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 270*a9b0838dSTaehee Yoo { 271*a9b0838dSTaehee Yoo struct aria_ctx *ctx = crypto_tfm_ctx(tfm); 272*a9b0838dSTaehee Yoo 273*a9b0838dSTaehee Yoo __aria_crypt(ctx, out, in, ctx->dec_key); 274*a9b0838dSTaehee Yoo } 275*a9b0838dSTaehee Yoo 276*a9b0838dSTaehee Yoo static struct crypto_alg aria_alg = { 277*a9b0838dSTaehee Yoo .cra_name = "aria", 278*a9b0838dSTaehee Yoo .cra_driver_name = "aria-generic", 279*a9b0838dSTaehee Yoo .cra_priority = 100, 280*a9b0838dSTaehee Yoo .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 281*a9b0838dSTaehee Yoo .cra_blocksize = ARIA_BLOCK_SIZE, 282*a9b0838dSTaehee Yoo .cra_ctxsize = sizeof(struct aria_ctx), 283*a9b0838dSTaehee Yoo .cra_alignmask = 3, 284*a9b0838dSTaehee Yoo .cra_module = THIS_MODULE, 285*a9b0838dSTaehee Yoo .cra_u = { 286*a9b0838dSTaehee Yoo .cipher = { 287*a9b0838dSTaehee Yoo .cia_min_keysize = ARIA_MIN_KEY_SIZE, 288*a9b0838dSTaehee Yoo .cia_max_keysize = ARIA_MAX_KEY_SIZE, 289*a9b0838dSTaehee Yoo .cia_setkey = aria_set_key, 290*a9b0838dSTaehee Yoo .cia_encrypt = __aria_encrypt, 291*a9b0838dSTaehee Yoo .cia_decrypt = __aria_decrypt 292*a9b0838dSTaehee Yoo } 293*a9b0838dSTaehee Yoo } 294*a9b0838dSTaehee Yoo }; 295*a9b0838dSTaehee Yoo 296*a9b0838dSTaehee Yoo static int __init aria_init(void) 297*a9b0838dSTaehee Yoo { 298*a9b0838dSTaehee Yoo return crypto_register_alg(&aria_alg); 299*a9b0838dSTaehee Yoo } 300*a9b0838dSTaehee Yoo 301*a9b0838dSTaehee Yoo static void __exit aria_fini(void) 302*a9b0838dSTaehee Yoo { 303*a9b0838dSTaehee Yoo crypto_unregister_alg(&aria_alg); 304*a9b0838dSTaehee Yoo } 305*a9b0838dSTaehee Yoo 306*a9b0838dSTaehee Yoo subsys_initcall(aria_init); 307*a9b0838dSTaehee Yoo module_exit(aria_fini); 308*a9b0838dSTaehee Yoo 309*a9b0838dSTaehee Yoo MODULE_DESCRIPTION("ARIA Cipher Algorithm"); 310*a9b0838dSTaehee Yoo MODULE_LICENSE("GPL"); 311*a9b0838dSTaehee Yoo MODULE_AUTHOR("Taehee Yoo <ap420073@gmail.com>"); 312*a9b0838dSTaehee Yoo MODULE_ALIAS_CRYPTO("aria"); 313*a9b0838dSTaehee Yoo MODULE_ALIAS_CRYPTO("aria-generic"); 314