[BACK]Return to camellia.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_ntl / crypt / camellia

Annotation of OpenXM/src/ox_ntl/crypt/camellia/camellia.c, Revision 1.1

1.1     ! iwane       1: /* $OpenXM$ */
        !             2: /*
        !             3:  * Camellia
        !             4:  * http://info.isl.ntt.co.jp/crypt/camellia/index.html
        !             5:  */
        !             6:
        !             7: #include "camellia.h"
        !             8:
        !             9:
        !            10: #if HAVE_CONFIG_H
        !            11: #include "config.h"
        !            12: #endif /* HAVE_CONFIG_H */
        !            13:
        !            14:
        !            15: #define leftrot32(x, n)      ((((uint32_t)x) << n) | ((uint32_t)x) >> (32 - n))
        !            16:
        !            17:
        !            18: #define DPRINTF(str, x, n)     /* DPRINTF__(str, (x), (n)) */
        !            19: #define DPRINTF__(str, x, n)   {                        \
        !            20:        int _i;                                  \
        !            21:        printf("%s: ", str);                      \
        !            22:        for (_i = 0; _i < n; _i++) {             \
        !            23:                printf("%02x", ARY(x, _i) & 0xff);    \
        !            24:                if (_i % 8 == 7)                 \
        !            25:                        printf(" ");             \
        !            26:        }                                        \
        !            27:        printf("\n");                            \
        !            28:        fflush(stdout);                          \
        !            29: }
        !            30:
        !            31: #ifdef WORDS_BIGENDIAN
        !            32: #define ARY(x, i)  (((uint8_t *)(x))[i])
        !            33: #else
        !            34: #define ARY(x, i)  (((uint8_t *)(x))[(int)("\x03\x02\x01\x00\x07\x06\x05\x04\x0b\x0a\x09\x08\x0f\x0e\x0d\x0c\x13\x12\x11\x10\x17\x16\x15\x14\x1b\x1a\x19\x18\x1f\x1e\x1d\x1c"[i])])
        !            35: #endif
        !            36:
        !            37:
        !            38: static const uint32_t G_camellia_sigma[] = {
        !            39:        0xa09e667f, 0x3bcc908b,
        !            40:        0xb67ae858, 0x4caa73b2,
        !            41:        0xc6ef372f, 0xe94f82be,
        !            42:        0x54ff53a5, 0xf1d36f1c,
        !            43:        0x10e527fa, 0xde682d1d,
        !            44:        0xb05688c2, 0xb3e6c1fd,
        !            45: };
        !            46:
        !            47: #define SIGMA(i)   (G_camellia_sigma + (2 * ((i) - 1)))
        !            48:
        !            49:
        !            50: static const uint8_t G_camellia_sbox[256] = {
        !            51:        112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
        !            52:         35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
        !            53:        134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
        !            54:        166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
        !            55:        139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
        !            56:        223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
        !            57:         20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
        !            58:        254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
        !            59:        170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
        !            60:         16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
        !            61:        135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
        !            62:         82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
        !            63:        233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
        !            64:        120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
        !            65:        114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
        !            66:         64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158,
        !            67: };
        !            68:
        !            69: #define SBOX1(n)       G_camellia_sbox[n]
        !            70: #define SBOX2(n)       (uint8_t)((SBOX1(n) >> 7 ^ SBOX1(n) << 1) & 0xff)
        !            71: #define SBOX3(n)       (uint8_t)((SBOX1(n) >> 1 ^ SBOX1(n) << 7) & 0xff)
        !            72: #define SBOX4(n)       SBOX1(((n) << 1 ^ (n) >> 7) & 0xff)
        !            73:
        !            74:
        !            75: #if 0
        !            76: static void
        !            77: camellia_binprt(const uint32_t *t, int n)
        !            78: {
        !            79:        int i;
        !            80:        int q, r;
        !            81:        for (i = 0; i < n; i++) {
        !            82:                q = i / 32;
        !            83:                r = i % 32;
        !            84:
        !            85:                printf("%d", (t[q] >> r) & 1);
        !            86:                if (i % 32 == 31)
        !            87:                        printf(" ");
        !            88:        }
        !            89:        printf("\n");
        !            90: }
        !            91: #endif
        !            92:
        !            93: /**
        !            94:  * return (a ^ b)
        !            95:  *  a - 128 bit
        !            96:  *  b - 128 bit
        !            97:  */
        !            98: static void
        !            99: camellia_xor128(uint32_t *t, const uint32_t *a, const uint32_t *b)
        !           100: {
        !           101:        int i;
        !           102:        for (i = 0; i < 4; i++) {
        !           103:                t[i] = a[i] ^ b[i];
        !           104:        }
        !           105: }
        !           106: static void
        !           107: camellia_xor64(uint32_t *t, const uint32_t *a, const uint32_t *b)
        !           108: {
        !           109:        int i;
        !           110:        for (i = 0; i < 2; i++) {
        !           111:                t[i] = a[i] ^ b[i];
        !           112:        }
        !           113: }
        !           114:
        !           115: static void
        !           116: camellia_rot128(uint32_t *t, const uint32_t *a, int n)
        !           117: {
        !           118:        const int N = 128 / 32;
        !           119:        int i;
        !           120:        int r = n % 32;
        !           121:        int r2 = 32 - r;
        !           122:        int q = (n / 32) % N;
        !           123:
        !           124:        if (r) {
        !           125:                for (i = 0; i < N; i++) {
        !           126:                        t[i] = (a[(i + q) % N] << r) | (a[(i + q + N + 1) % N] >> r2);
        !           127:                }
        !           128:        } else {
        !           129:                for (i = 0; i < N; i++) {
        !           130:                        t[i] = a[(i + q) % N];
        !           131:                }
        !           132:        }
        !           133: }
        !           134:
        !           135:
        !           136:
        !           137:
        !           138: /**
        !           139:  * return s(l)
        !           140:  *  t - 64 bit
        !           141:  *  l - 64 bit
        !           142:  */
        !           143: static inline void
        !           144: camellia_s(uint32_t *t, const uint32_t *l)
        !           145: {
        !           146:        ARY(t, 0) = SBOX1(ARY(l, 0));
        !           147:        ARY(t, 1) = SBOX2(ARY(l, 1));
        !           148:        ARY(t, 2) = SBOX3(ARY(l, 2));
        !           149:        ARY(t, 3) = SBOX4(ARY(l, 3));
        !           150:        ARY(t, 4) = SBOX2(ARY(l, 4));
        !           151:        ARY(t, 5) = SBOX3(ARY(l, 5));
        !           152:        ARY(t, 6) = SBOX4(ARY(l, 6));
        !           153:        ARY(t, 7) = SBOX1(ARY(l, 7));
        !           154: }
        !           155:
        !           156:
        !           157: /**
        !           158:  * return p(l)
        !           159:  *  t - 64 bit
        !           160:  *  l - 64 bit
        !           161:  */
        !           162: static inline void
        !           163: camellia_p(uint32_t *t, const uint32_t *l)
        !           164: {
        !           165: #define L(i) (ARY(l, (i) - 1))
        !           166:        ARY(t, 0) = L(1) ^ L(3) ^ L(4) ^ L(6) ^ L(7) ^ L(8);
        !           167:        ARY(t, 1) = L(1) ^ L(2) ^ L(4) ^ L(5) ^ L(7) ^ L(8);
        !           168:        ARY(t, 2) = L(1) ^ L(2) ^ L(3) ^ L(5) ^ L(6) ^ L(8);
        !           169:        ARY(t, 3) = L(2) ^ L(3) ^ L(4) ^ L(5) ^ L(6) ^ L(7);
        !           170:        ARY(t, 4) = L(1) ^ L(2) ^ L(6) ^ L(7) ^ L(8);
        !           171:        ARY(t, 5) = L(2) ^ L(3) ^ L(5) ^ L(7) ^ L(8);
        !           172:        ARY(t, 6) = L(3) ^ L(4) ^ L(5) ^ L(6) ^ L(8);
        !           173:        ARY(t, 7) = L(1) ^ L(4) ^ L(5) ^ L(6) ^ L(7);
        !           174: #undef L
        !           175: }
        !           176:
        !           177:
        !           178: /**
        !           179:  * return p(s(x^k))
        !           180:  *  t - 64 bit
        !           181:  *  l - 64 bit
        !           182:  */
        !           183: static inline void
        !           184: camellia_f(uint32_t *y, const uint32_t *x, const uint32_t *k)
        !           185: {
        !           186:        uint32_t xor[4];
        !           187:        uint32_t s[4];
        !           188:
        !           189:        camellia_xor64(xor, x, k);
        !           190:        camellia_s(s, xor);
        !           191:        camellia_p(y, s);
        !           192: }
        !           193:
        !           194:
        !           195: /**
        !           196:  * kl :  64 bit
        !           197:  * kr :  64 bit
        !           198:  * smg:  64 bit
        !           199:  */
        !           200: static inline void
        !           201: camellia_feistel(uint32_t *w, const uint32_t *kl, const uint32_t *kr, const uint32_t *sgm)
        !           202: {
        !           203:        camellia_f(w, kl, sgm);
        !           204:        camellia_xor64(w, w, kr);
        !           205: }
        !           206:
        !           207: static inline void
        !           208: camellia_fl(uint32_t *y, const uint32_t *x, const uint32_t *k)
        !           209: {
        !           210:        uint32_t t;
        !           211:
        !           212:        t = x[0] & k[0];
        !           213:        y[1] = leftrot32(t, 1) ^ x[1];
        !           214:        y[0] = (y[1] | k[1]) ^ x[0];
        !           215: }
        !           216:
        !           217: static inline void
        !           218: camellia_fl_(uint32_t *x, const uint32_t *y, const uint32_t *k)
        !           219: {
        !           220:        uint32_t t;
        !           221:
        !           222:        x[0] = (y[1] | k[1]) ^ y[0];
        !           223:        t = x[0] & k[0];
        !           224:        x[1] = leftrot32(t, 1) ^ y[1];
        !           225: }
        !           226:
        !           227:
        !           228:
        !           229: /*
        !           230:  * len =  16 or  24 or  32
        !           231:  * bit = 128 or 192 or 256
        !           232:  */
        !           233: int
        !           234: camellia_keyset(const unsigned char *key, int len, camellia_key *ckey)
        !           235: {
        !           236:        int i;
        !           237:        const uint32_t *kr, *kl, *kb;
        !           238:        uint32_t ka[4];
        !           239:        uint32_t t[4];  /* 128 bit */
        !           240:        uint32_t w[4];  /* 128 bit */
        !           241:        uint32_t v[4];  /* 128 bit */
        !           242:
        !           243: #define Kl(i) (ARY(ckey->key, i))
        !           244: #define Kr(i) (ARY(ckey->key, (i + 16)))
        !           245: #define T(i)  (ARY(t,  i))
        !           246:
        !           247:        if (len == 16) {
        !           248:                for (i = 0; i < 16; i++) {
        !           249:                        Kl(i) = key[i];
        !           250:                        Kr(i) = 0x00;
        !           251:                }
        !           252:        } else if (len == 24) {
        !           253:                for (i = 0; i < 16; i++) {
        !           254:                        Kl(i) = key[i];
        !           255:                }
        !           256:                for (; i < 24; i++) {
        !           257:                        Kr(i - 16) = key[i];
        !           258:                        Kr(i - 8) = ~key[i];
        !           259:                }
        !           260:        } else if (len == 32) {
        !           261:                for (i = 0; i < 16; i++) {
        !           262:                        Kl(i) = key[i];
        !           263:                        Kr(i) = key[i + 16];
        !           264:                }
        !           265:        } else {
        !           266:                return (-1);
        !           267:        }
        !           268:
        !           269:        kl = ckey->key;
        !           270:        kr = ckey->key + 4;
        !           271:
        !           272:        ckey->len = len;
        !           273:
        !           274:        camellia_xor128(t, kl, kr);
        !           275:
        !           276:
        !           277:        camellia_feistel(w + 2, t, t + 2, SIGMA(1));
        !           278:        camellia_feistel(w, w + 2, t, SIGMA(2));
        !           279:
        !           280:        camellia_xor128(v, w, kl);
        !           281:
        !           282:        camellia_feistel(w + 2, v, v + 2, SIGMA(3));
        !           283:        camellia_feistel(w, w + 2, v, SIGMA(4));
        !           284:
        !           285:        if (len == 16) {
        !           286:                /*
        !           287:                 * KA = w
        !           288:                 * KL = key
        !           289:                 */
        !           290:                camellia_rot128(ckey->kw, ckey->key, 0);
        !           291:                camellia_rot128(ckey->kw + 4, w, 111);
        !           292:
        !           293:                camellia_rot128(ckey->kl, w, 30);
        !           294:                camellia_rot128(ckey->kl + 4, ckey->key, 77);
        !           295:
        !           296:                camellia_rot128(ckey->k +  0, w, 0);
        !           297:                camellia_rot128(ckey->k +  4, ckey->key, 15);
        !           298:                camellia_rot128(ckey->k +  8, w, 15);
        !           299:                camellia_rot128(ckey->k + 12, ckey->key, 45);
        !           300:                camellia_rot128(ckey->k + 16, w, 45);
        !           301:                camellia_rot128(ckey->k + 20, w, 60);
        !           302:                camellia_rot128(ckey->k + 24, ckey->key, 94);
        !           303:                camellia_rot128(ckey->k + 28, w, 94);
        !           304:                camellia_rot128(ckey->k + 32, ckey->key, 111);
        !           305:
        !           306:                camellia_rot128(v, ckey->key, 60);
        !           307:                ckey->k[18] = v[2];
        !           308:                ckey->k[19] = v[3];
        !           309:
        !           310:                return (0);
        !           311:        }
        !           312:
        !           313:        memcpy(ka, w, sizeof(w));
        !           314:
        !           315:        camellia_xor128(v, w, kr);
        !           316:
        !           317:        camellia_feistel(w + 2, v, v + 2, SIGMA(5));
        !           318:        camellia_feistel(w + 0, w + 2, v, SIGMA(6));
        !           319:
        !           320:        kb = w;
        !           321:
        !           322:        camellia_rot128(ckey->kw + 0, kl, 0);
        !           323:        camellia_rot128(ckey->kw + 4, kb, 111);
        !           324:
        !           325:        camellia_rot128(ckey->kl + 0, kr, 30);
        !           326:        camellia_rot128(ckey->kl + 4, kl, 60);
        !           327:        camellia_rot128(ckey->kl + 8, ka, 77);
        !           328:
        !           329:        camellia_rot128(ckey->k +  0, kb, 0);
        !           330:        camellia_rot128(ckey->k +  4, kr, 15);
        !           331:        camellia_rot128(ckey->k +  8, ka, 15);
        !           332:        camellia_rot128(ckey->k + 12, kb, 30);
        !           333:        camellia_rot128(ckey->k + 16, kl, 45);
        !           334:        camellia_rot128(ckey->k + 20, ka, 45);
        !           335:
        !           336:        camellia_rot128(ckey->k + 24, kr, 60);
        !           337:        camellia_rot128(ckey->k + 28, kb, 60);
        !           338:        camellia_rot128(ckey->k + 32, kl, 77);
        !           339:        camellia_rot128(ckey->k + 36, kr, 94);
        !           340:        camellia_rot128(ckey->k + 40, ka, 94);
        !           341:        camellia_rot128(ckey->k + 44, kl, 111);
        !           342:
        !           343:
        !           344:        return (0);
        !           345: #undef X
        !           346: }
        !           347:
        !           348:
        !           349: /*
        !           350:  * m: message 128 bit
        !           351:  * e: encrypt 128 bit
        !           352:  */
        !           353: void
        !           354: camellia_enc(camellia_key *ckey, const uint8_t *msg, uint8_t *e)
        !           355: {
        !           356:        uint32_t m[4];
        !           357:        uint32_t w[8] = {0, 0, 0, 0, 0, 0, 0, 0};
        !           358:        int i, j, k;
        !           359:        int loop;
        !           360:
        !           361:
        !           362:        if (ckey->len == 16) { /* 128 bit */
        !           363:                loop = 2;
        !           364:        } else {               /* 192 or 256 bit */
        !           365:                loop = 3;
        !           366:        }
        !           367:
        !           368:        for (i = 0; i < 16; i++) {
        !           369:                ARY(m, i) = msg[i];
        !           370:        }
        !           371:
        !           372:        for (i = 0; i < 4; i++) {
        !           373:                w[(i + 2) % 4] = m[i] ^ ckey->kw[i];
        !           374:        }
        !           375:
        !           376:        i = 0;
        !           377:        for (j = 0;; j++) {
        !           378:
        !           379:                for (k = 0; k < 6; k++, i++) {
        !           380:                        camellia_feistel(w + (4 + 2 * k) % 8, w + (2 + 2 * k) % 8, w + (0 + 2 * k) % 8, ckey->k + 2 * i);
        !           381:                }
        !           382:
        !           383:                if (j == loop)
        !           384:                        break;
        !           385:
        !           386:                camellia_fl(w + 2, w + 6, ckey->kl + 4 * j);
        !           387:                camellia_fl_(w + 0, w + 4, ckey->kl + 4 * j + 2);
        !           388:
        !           389:        }
        !           390:
        !           391:
        !           392:        camellia_xor128(w, w + 4, ckey->kw + 4);
        !           393:
        !           394:        for (i = 0; i < 32; i++) {
        !           395:                e[i] = ARY(w, i);
        !           396:        }
        !           397:
        !           398: }
        !           399:
        !           400: /*
        !           401:  * e: encrypt 128 bit
        !           402:  * m: message 128 bit
        !           403:  */
        !           404: void
        !           405: camellia_dec(camellia_key *ckey, const uint8_t *enc, uint8_t *m)
        !           406: {
        !           407:        uint32_t e[4];
        !           408:        uint32_t w[8] = {0, 0, 0, 0, 0, 0, 0, 0};
        !           409:        int i, j, k;
        !           410:        int loop;
        !           411:
        !           412:        if (ckey->len == 16) { /* 128 bit */
        !           413:                loop = 2;
        !           414: /*18*/
        !           415:        } else {
        !           416:                loop = 3;
        !           417: /*24*/
        !           418:        }
        !           419:
        !           420:        for (i = 0; i < 16; i++) {
        !           421:                ARY(e, i) = enc[i];
        !           422:        }
        !           423:
        !           424:
        !           425:        for (i = 0; i < 4; i++) {
        !           426:                w[(i + 2) % 4] = e[i] ^ ckey->kw[(i + 0) % 4 + 4];
        !           427:        }
        !           428:
        !           429:
        !           430:        i = (loop + 1) * 6 - 1;
        !           431:        for (j = loop - 1;; j--) {
        !           432:
        !           433:                for (k = 0; k < 6; k++, i--) {
        !           434:                        camellia_feistel(w + (4 + 2 * k) % 8, w + (2 + 2 * k) % 8, w + (0 + 2 * k) % 8, ckey->k + 2 * i);
        !           435:                }
        !           436:
        !           437:                if (j < 0)
        !           438:                        break;
        !           439:
        !           440:
        !           441:                camellia_fl(w + 2, w + 6, ckey->kl + 4 * j + 2);
        !           442:                camellia_fl_(w + 0, w + 4, ckey->kl + 4 * j + 0);
        !           443:
        !           444:        }
        !           445:
        !           446:
        !           447:        camellia_xor128(w, w + 4, ckey->kw + 0);
        !           448:
        !           449:        for (i = 0; i < 32; i++) {
        !           450:                m[i] = ARY(w, i);
        !           451:        }
        !           452:
        !           453: }
        !           454:
        !           455:
        !           456:
        !           457: /* End of File */
        !           458:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>