1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* LibTomCrypt, modular cryptographic library -- Tom St Denis 2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LibTomCrypt is a library that provides various cryptographic 4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * algorithms in a highly modular and flexible manner. 5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The library is free for all purposes without any express 7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * guarantee it works. 8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com 10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @file kasumi.c 14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Implementation of the 3GPP Kasumi block cipher 15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Derived from the 3GPP standard source code 16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "tomcrypt.h" 19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_KASUMI 21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projecttypedef unsigned u16; 23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ROL16(x, y) ((((x)<<(y)) | ((x)>>(16-(y)))) & 0xFFFF) 25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_cipher_descriptor kasumi_desc = { 27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project "kasumi", 28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 21, 29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 16, 16, 8, 8, 30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &kasumi_setup, 31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &kasumi_ecb_encrypt, 32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &kasumi_ecb_decrypt, 33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &kasumi_test, 34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &kasumi_done, 35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &kasumi_keysize, 36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}; 38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic u16 FI( u16 in, u16 subkey ) 40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project u16 nine, seven; 42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project static const u16 S7[128] = { 43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18,123, 33, 44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 55,113, 39,114, 21, 67, 65, 12, 47, 73, 46, 27, 25,111,124, 81, 45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 53, 9,121, 79, 52, 60, 58, 48,101,127, 40,120,104, 70, 71, 43, 46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 20,122, 72, 61, 23,109, 13,100, 77, 1, 16, 7, 82, 10,105, 98, 47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 117,116, 76, 11, 89,106, 0,125,118, 99, 86, 69, 30, 57,126, 87, 48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66, 49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29,115, 44, 50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 64,107,108, 24,110, 83, 36, 78, 42, 19, 15, 41, 88,119, 59, 3 }; 51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project static const u16 S9[512] = { 52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 167,239,161,379,391,334, 9,338, 38,226, 48,358,452,385, 90,397, 53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 183,253,147,331,415,340, 51,362,306,500,262, 82,216,159,356,177, 54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 175,241,489, 37,206, 17, 0,333, 44,254,378, 58,143,220, 81,400, 55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 95, 3,315,245, 54,235,218,405,472,264,172,494,371,290,399, 76, 56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 165,197,395,121,257,480,423,212,240, 28,462,176,406,507,288,223, 57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 501,407,249,265, 89,186,221,428,164, 74,440,196,458,421,350,163, 58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 232,158,134,354, 13,250,491,142,191, 69,193,425,152,227,366,135, 59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 344,300,276,242,437,320,113,278, 11,243, 87,317, 36, 93,496, 27, 60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 487,446,482, 41, 68,156,457,131,326,403,339, 20, 39,115,442,124, 61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 475,384,508, 53,112,170,479,151,126,169, 73,268,279,321,168,364, 62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 363,292, 46,499,393,327,324, 24,456,267,157,460,488,426,309,229, 63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 439,506,208,271,349,401,434,236, 16,209,359, 52, 56,120,199,277, 64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 465,416,252,287,246, 6, 83,305,420,345,153,502, 65, 61,244,282, 65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 173,222,418, 67,386,368,261,101,476,291,195,430, 49, 79,166,330, 66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 280,383,373,128,382,408,155,495,367,388,274,107,459,417, 62,454, 67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 132,225,203,316,234, 14,301, 91,503,286,424,211,347,307,140,374, 68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 35,103,125,427, 19,214,453,146,498,314,444,230,256,329,198,285, 69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 50,116, 78,410, 10,205,510,171,231, 45,139,467, 29, 86,505, 32, 70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 72, 26,342,150,313,490,431,238,411,325,149,473, 40,119,174,355, 71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 185,233,389, 71,448,273,372, 55,110,178,322, 12,469,392,369,190, 72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 1,109,375,137,181, 88, 75,308,260,484, 98,272,370,275,412,111, 73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 336,318, 4,504,492,259,304, 77,337,435, 21,357,303,332,483, 18, 74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 47, 85, 25,497,474,289,100,269,296,478,270,106, 31,104,433, 84, 75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 414,486,394, 96, 99,154,511,148,413,361,409,255,162,215,302,201, 76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 266,351,343,144,441,365,108,298,251, 34,182,509,138,210,335,133, 77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 311,352,328,141,396,346,123,319,450,281,429,228,443,481, 92,404, 78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 485,422,248,297, 23,213,130,466, 22,217,283, 70,294,360,419,127, 79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 312,377, 7,468,194, 2,117,295,463,258,224,447,247,187, 80,398, 80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 284,353,105,390,299,471,470,184, 57,200,348, 63,204,188, 33,451, 81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 97, 30,310,219, 94,160,129,493, 64,179,263,102,189,207,114,402, 82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 438,477,387,122,192, 42,381, 5,145,118,180,449,293,323,136,380, 83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 43, 66, 60,455,341,445,202,432, 8,237, 15,376,436,464, 59,461}; 84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* The sixteen bit input is split into two unequal halves, * 86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * nine bits and seven bits - as is the subkey */ 87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project nine = (u16)(in>>7)&0x1FF; 89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project seven = (u16)(in&0x7F); 90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Now run the various operations */ 92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project nine = (u16)(S9[nine] ^ seven); 93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project seven = (u16)(S7[seven] ^ (nine & 0x7F)); 94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project seven ^= (subkey>>9); 95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project nine ^= (subkey&0x1FF); 96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project nine = (u16)(S9[nine] ^ seven); 97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project seven = (u16)(S7[seven] ^ (nine & 0x7F)); 98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return (u16)(seven<<9) + nine; 99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic ulong32 FO( ulong32 in, int round_no, symmetric_key *key) 102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project u16 left, right; 104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Split the input into two 16-bit words */ 106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left = (u16)(in>>16); 107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project right = (u16) in&0xFFFF; 108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Now apply the same basic transformation three times */ 110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left ^= key->kasumi.KOi1[round_no]; 111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left = FI( left, key->kasumi.KIi1[round_no] ); 112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left ^= right; 113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project right ^= key->kasumi.KOi2[round_no]; 115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project right = FI( right, key->kasumi.KIi2[round_no] ); 116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project right ^= left; 117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left ^= key->kasumi.KOi3[round_no]; 119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left = FI( left, key->kasumi.KIi3[round_no] ); 120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left ^= right; 121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return (((ulong32)right)<<16)+left; 123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic ulong32 FL( ulong32 in, int round_no, symmetric_key *key ) 126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project u16 l, r, a, b; 128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* split out the left and right halves */ 129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project l = (u16)(in>>16); 130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project r = (u16)(in)&0xFFFF; 131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* do the FL() operations */ 132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project a = (u16) (l & key->kasumi.KLi1[round_no]); 133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project r ^= ROL16(a,1); 134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project b = (u16)(r | key->kasumi.KLi2[round_no]); 135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project l ^= ROL16(b,1); 136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* put the two halves back together */ 137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return (((ulong32)l)<<16) + r; 139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 left, right, temp; 144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int n; 145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(pt != NULL); 147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(ct != NULL); 148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(skey != NULL); 149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LOAD32H(left, pt); 151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LOAD32H(right, pt+4); 152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (n = 0; n <= 7; ) { 154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project temp = FL(left, n, skey); 155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project temp = FO(temp, n++, skey); 156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project right ^= temp; 157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project temp = FO(right, n, skey); 158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project temp = FL(temp, n++, skey); 159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left ^= temp; 160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project STORE32H(left, ct); 163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project STORE32H(right, ct+4); 164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 left, right, temp; 171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int n; 172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(pt != NULL); 174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(ct != NULL); 175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(skey != NULL); 176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LOAD32H(left, ct); 178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LOAD32H(right, ct+4); 179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (n = 7; n >= 0; ) { 181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project temp = FO(right, n, skey); 182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project temp = FL(temp, n--, skey); 183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project left ^= temp; 184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project temp = FL(left, n, skey); 185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project temp = FO(temp, n--, skey); 186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project right ^= temp; 187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project STORE32H(left, pt); 190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project STORE32H(right, pt+4); 191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) 196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project static const u16 C[8] = { 0x0123,0x4567,0x89AB,0xCDEF, 0xFEDC,0xBA98,0x7654,0x3210 }; 198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project u16 ukey[8], Kprime[8]; 199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int n; 200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(key != NULL); 202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(skey != NULL); 203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (keylen != 16) { 205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_INVALID_KEYSIZE; 206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (num_rounds != 0 && num_rounds != 8) { 209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_INVALID_ROUNDS; 210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Start by ensuring the subkeys are endian correct on a 16-bit basis */ 213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (n = 0; n < 8; n++ ) { 214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ukey[n] = (((u16)key[2*n]) << 8) | key[2*n+1]; 215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Now build the K'[] keys */ 218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (n = 0; n < 8; n++) { 219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Kprime[n] = ukey[n] ^ C[n]; 220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Finally construct the various sub keys */ 223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for(n = 0; n < 8; n++) { 224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project skey->kasumi.KLi1[n] = ROL16(ukey[n],1); 225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project skey->kasumi.KLi2[n] = Kprime[(n+2)&0x7]; 226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project skey->kasumi.KOi1[n] = ROL16(ukey[(n+1)&0x7],5); 227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project skey->kasumi.KOi2[n] = ROL16(ukey[(n+5)&0x7],8); 228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project skey->kasumi.KOi3[n] = ROL16(ukey[(n+6)&0x7],13); 229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project skey->kasumi.KIi1[n] = Kprime[(n+4)&0x7]; 230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project skey->kasumi.KIi2[n] = Kprime[(n+3)&0x7]; 231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project skey->kasumi.KIi3[n] = Kprime[(n+7)&0x7]; 232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid kasumi_done(symmetric_key *skey) 238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint kasumi_keysize(int *keysize) 242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(keysize != NULL); 244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (*keysize >= 16) { 245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *keysize = 16; 246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } else { 248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_INVALID_KEYSIZE; 249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint kasumi_test(void) 253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef LTC_TEST 255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_NOP; 256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else 257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project static const struct { 258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char key[16], pt[8], ct[8]; 259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } tests[] = { 260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x4B, 0x58, 0xA7, 0x71, 0xAF, 0xC7, 0xE5, 0xE8 } 265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}, 266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x7E, 0xEF, 0x11, 0x3C, 0x95, 0xBB, 0x5A, 0x77 } 271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}, 272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x5F, 0x14, 0x06, 0x86, 0xD7, 0xAD, 0x5A, 0x39 }, 277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}, 278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x2E, 0x14, 0x91, 0xCF, 0x70, 0xAA, 0x46, 0x5D } 283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}, 284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 }, 287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0xB5, 0x45, 0x86, 0xF4, 0xAB, 0x9A, 0xE5, 0x46 } 289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}, 290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}; 292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char buf[2][8]; 293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project symmetric_key key; 294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int err, x; 295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { 297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = kasumi_setup(tests[x].key, 16, 0, &key)) != CRYPT_OK) { 298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = kasumi_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) { 301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = kasumi_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) { 304f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 305f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 306f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (XMEMCMP(tests[x].pt, buf[1], 8) || XMEMCMP(tests[x].ct, buf[0], 8)) { 307f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_FAIL_TESTVECTOR; 308f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 309f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 310f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 311f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 312f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 313f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 314f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 315f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 316f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/kasumi.c,v $ */ 317f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.7 $ */ 318f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/11/09 03:05:44 $ */ 319