Annotation of OpenXM/src/ox_ntl/crypt/des/des.c, Revision 1.1
1.1 ! iwane 1: /* $OpenXM$ */
! 2: /*
! 3: * FIPS PUB 46-3
! 4: * DATA ENCRYPTION STANDARD
! 5: */
! 6: #include <stdio.h>
! 7:
! 8: #include "des.h"
! 9: #include "block.h"
! 10:
! 11: #define BLOCK 8
! 12:
! 13: #define inline inline
! 14:
! 15: /*===========================================================*
! 16: * KEY STRUCT
! 17: *===========================================================*/
! 18: static int inline
! 19: keychk0(uint32_t n)
! 20: {
! 21: int i, j, c;
! 22:
! 23: for (i = 0; i < 4; i++) {
! 24: c = 0;
! 25: for (j = 0; j < 8; j++) {
! 26: if ((n >> (8 * i + j)) & 1)
! 27: c++;
! 28: }
! 29: if (c % 2 == 0)
! 30: return (0);
! 31: }
! 32: return (1);
! 33: }
! 34:
! 35: int
! 36: des_keychk(des_key *key)
! 37: {
! 38: return (keychk0(key->key.ui[0]) & keychk0(key->key.ui[1]));
! 39: }
! 40:
! 41: void
! 42: des_keyset(const unsigned char *key, des_key *dkey)
! 43: {
! 44: uint32_t k;
! 45: int i, j;
! 46:
! 47: for (j = 0; j < 2; j++) {
! 48: k = 0;
! 49: for (i = 0; i < 4; i++) {
! 50: k |= (key[i + 4 * j] & 0xff) << (8 * (3 - i));
! 51: }
! 52: dkey->key.ui[j] = k;
! 53: }
! 54:
! 55: }
! 56:
! 57:
! 58: #ifdef DES_DEBUG
! 59: /*===========================================================*
! 60: * DEBUG
! 61: *===========================================================*/
! 62: static void
! 63: pr(uint32_t n)
! 64: {
! 65: int i;
! 66:
! 67: for (i = 31; i >= 0; i--) {
! 68: printf("%d", (n >> i) & 1);
! 69: if (i % 8 == 0)
! 70: printf(" ");
! 71: }
! 72: }
! 73: #endif
! 74:
! 75:
! 76: /*===========================================================*
! 77: * SHIFT
! 78: *===========================================================*/
! 79: static const int SHIFT_IDX[] = {
! 80: 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
! 81: };
! 82:
! 83: static inline uint32_t
! 84: lshift28(uint32_t x, int c)
! 85: {
! 86: int n = SHIFT_IDX[c];
! 87: return (((x << n) | (x >> (28 - n))) & 0x0fffffff);
! 88: }
! 89:
! 90: static inline uint32_t
! 91: rshift28(uint32_t x, int c)
! 92: {
! 93: int n = SHIFT_IDX[15 - c];
! 94: return (((x >> n) | (x << (28 - n))) & 0x0fffffff);
! 95: }
! 96:
! 97:
! 98:
! 99: /*===========================================================*
! 100: * TRANS
! 101: *===========================================================*/
! 102: static void
! 103: trans(uint32_t li, uint32_t ri, uint32_t *lo, uint32_t *ro, const int *index, int m)
! 104: {
! 105: int idx, n;
! 106: uint32_t a[2];
! 107: uint32_t r, l;
! 108: const static int N = 32;
! 109:
! 110: a[0] = li;
! 111: a[1] = ri;
! 112:
! 113: l = 0;
! 114: r = 0;
! 115: for (n = 0; n < N; n++) {
! 116: idx = index[n];
! 117: l |= ((a[idx / N] >> (N - (idx % N) - 1)) & 1) << (N - n - 1);
! 118: }
! 119:
! 120: for (; n < m; n++) {
! 121: idx = index[n];
! 122: r |= ((a[idx / N] >> (N - (idx % N) - 1)) & 1) << (2 * N - n - 1);
! 123: }
! 124:
! 125: *lo = l;
! 126: *ro = r;
! 127: }
! 128:
! 129:
! 130:
! 131:
! 132: /*
! 133: * input 64 bit 32+32
! 134: * output 64 bit 32+32
! 135: */
! 136: static void
! 137: ip(uint32_t li, uint32_t ri, uint32_t *lo, uint32_t *ro)
! 138: {
! 139: static const int INDEX[] = {
! 140: 57, 49, 41, 33, 25, 17, 9, 1,
! 141: 59, 51, 43, 35, 27, 19, 11, 3,
! 142: 61, 53, 45, 37, 29, 21, 13, 5,
! 143: 63, 55, 47, 39, 31, 23, 15, 7,
! 144: 56, 48, 40, 32, 24, 16, 8, 0,
! 145: 58, 50, 42, 34, 26, 18, 10, 2,
! 146: 60, 52, 44, 36, 28, 20, 12, 4,
! 147: 62, 54, 46, 38, 30, 22, 14, 6,
! 148: };
! 149:
! 150: trans(li, ri, lo, ro, INDEX, 64);
! 151: }
! 152:
! 153:
! 154: /*
! 155: * input 64 bit 32+32
! 156: * output 64 bit 32+32
! 157: */
! 158: static void
! 159: ip_inv(uint32_t li, uint32_t ri, uint32_t *lo, uint32_t *ro)
! 160: {
! 161: static const int INDEX[] = {
! 162: 39, 7, 47, 15, 55, 23, 63, 31,
! 163: 38, 6, 46, 14, 54, 22, 62, 30,
! 164: 37, 5, 45, 13, 53, 21, 61, 29,
! 165: 36, 4, 44, 12, 52, 20, 60, 28,
! 166: 35, 3, 43, 11, 51, 19, 59, 27,
! 167: 34, 2, 42, 10, 50, 18, 58, 26,
! 168: 33, 1, 41, 9, 49, 17, 57, 25,
! 169: 32, 0, 40, 8, 48, 16, 56, 24,
! 170: };
! 171:
! 172: trans(li, ri, lo, ro, INDEX, 64);
! 173: }
! 174:
! 175:
! 176:
! 177: /* PC1
! 178: * input 64 bit 32+32
! 179: * output 56 bit 28+28
! 180: */
! 181: static void
! 182: ktrans1(uint32_t li, uint32_t ri, uint32_t *lo, uint32_t *ro)
! 183: {
! 184: static const int INDEX[] = {
! 185: 0, 0, 0, 0,
! 186: 56, 48, 40, 32, 24, 16, 8,
! 187: 0, 57, 49, 41, 33, 25, 17,
! 188: 9, 1, 58, 50, 42, 34, 26,
! 189: 18, 10, 2, 59, 51, 43, 35,
! 190: 0, 0, 0, 0,
! 191: 62, 54, 46, 38, 30, 22, 14,
! 192: 6, 61, 53, 45, 37, 29, 21,
! 193: 13, 5, 60, 52, 44, 36, 28,
! 194: 20, 12, 4, 27, 19, 11, 3,
! 195: };
! 196:
! 197: trans(li, ri, lo, ro, INDEX, 64);
! 198:
! 199: *lo &= 0x0fffffff;
! 200: *ro &= 0x0fffffff;
! 201: }
! 202:
! 203:
! 204: /* PC2
! 205: * Input 56 bit = 28+28
! 206: * Output 48 bit = 32+16
! 207: */
! 208: static void
! 209: ktrans2(uint32_t li, uint32_t ri, uint32_t *lo, uint32_t *ro)
! 210: {
! 211: uint32_t l, r;
! 212: static const int CTRANS2_INDEX[64] = {
! 213: 13, 16, 10, 23, 0, 4,
! 214: 2, 27, 14, 5, 20, 9,
! 215: 22, 18, 11, 3, 25, 7,
! 216: 15, 6, 26, 19, 12, 1,
! 217: 40, 51, 30, 36, 46, 54,
! 218: 29, 39, 50, 44, 32, 47,
! 219: 43, 48, 38, 55, 33, 52,
! 220: 45, 41, 49, 35, 28, 31,
! 221: };
! 222:
! 223: l = (li << 4) | ((ri >> 24) & 0xf);
! 224: r = ri << 8;
! 225:
! 226: trans(l, r, lo, ro, CTRANS2_INDEX, 48);
! 227:
! 228: *ro &= 0xffff0000;
! 229: }
! 230:
! 231: /*
! 232: * input 32 bit = 32
! 233: * output 48 bit = 32 + 16
! 234: */
! 235: static void
! 236: etrans1(uint32_t li, uint32_t *lo, uint32_t *ro)
! 237: {
! 238: uint32_t dummy = 0;
! 239: static const int INDEX[64] = {
! 240: 31, 0, 1, 2, 3, 4,
! 241: 3, 4, 5, 6, 7, 8,
! 242: 7, 8, 9, 10, 11, 12,
! 243: 11, 12, 13, 14, 15, 16,
! 244: 15, 16, 17, 18, 19, 20,
! 245: 19, 20, 21, 22, 23, 24,
! 246: 23, 24, 25, 26, 27, 28,
! 247: 27, 28, 29, 30, 31, 0,
! 248: };
! 249:
! 250: trans(li, dummy, lo, ro, INDEX, 48);
! 251: }
! 252:
! 253:
! 254: /*
! 255: * input 32 bit = 32
! 256: * output 32 bit = 32
! 257: */
! 258: static uint32_t
! 259: etrans2(uint32_t n)
! 260: {
! 261: static const int INDEX[64] = {
! 262: 15, 6, 19, 20,
! 263: 28, 11, 27, 16,
! 264: 0, 14, 22, 25,
! 265: 4, 17, 30, 9,
! 266: 1, 7, 23, 13,
! 267: 31, 26, 2, 8,
! 268: 18, 12, 29, 5,
! 269: 21, 10, 3, 24,
! 270: };
! 271:
! 272: uint32_t p, b;
! 273:
! 274: trans(n, 0, &p, &b, INDEX, 48);
! 275:
! 276: return (p);
! 277: }
! 278:
! 279: /*
! 280: * input : 6 bit
! 281: * oiutput: 6 bit
! 282: */
! 283: static uint32_t
! 284: strans1(uint32_t s, int n)
! 285: {
! 286: static const int S[][4 * 16] = {
! 287: {
! 288: 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
! 289: 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
! 290: 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
! 291: 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
! 292: }, {
! 293: 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
! 294: 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
! 295: 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
! 296: 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
! 297: }, {
! 298: 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
! 299: 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
! 300: 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
! 301: 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
! 302: }, {
! 303: 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
! 304: 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
! 305: 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
! 306: 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
! 307: }, {
! 308: 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
! 309: 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
! 310: 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
! 311: 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
! 312: }, {
! 313: 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
! 314: 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
! 315: 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
! 316: 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
! 317: }, {
! 318: 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
! 319: 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
! 320: 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
! 321: 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
! 322: }, {
! 323: 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
! 324: 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
! 325: 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
! 326: 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
! 327: },
! 328: };
! 329:
! 330: int x, y;
! 331:
! 332: x = (((s >> 5) & 1) << 1) | (s & 1);
! 333: y = (s >> 1) & 0xf;
! 334:
! 335: return (S[n][16 * x + y]);
! 336:
! 337: }
! 338:
! 339: /*
! 340: * input : 48 bit
! 341: * output: 32 bit
! 342: */
! 343: static void
! 344: strans(uint32_t li, uint32_t ri, uint32_t *out)
! 345: {
! 346: int i;
! 347: int m;
! 348:
! 349: uint32_t s[8];
! 350: uint32_t ui;
! 351:
! 352: /* ... X-( */
! 353: s[0] = li >> 26;
! 354: s[1] = (li >> 20) & 0x3f;
! 355: s[2] = (li >> 14) & 0x3f;
! 356: s[3] = (li >> 8) & 0x3f;
! 357: s[4] = (li >> 2) & 0x3f;
! 358: s[5] = ((li & 0x3) << 4) | (ri >> 28);
! 359: s[6] = (ri >> 22) & 0x3f;
! 360: s[7] = (ri >> 16) & 0x3f;
! 361:
! 362: ui = 0;
! 363: for (i = 0; i < 8; i++) {
! 364: m = strans1(s[i], i);
! 365: ui |= m << 4 * (7 - i);
! 366: }
! 367:
! 368: *out = ui;
! 369: }
! 370:
! 371:
! 372: /*
! 373: * input : r : 32 bit
! 374: * : k : 48 bit = 32+16
! 375: * output: 32 bit
! 376: */
! 377: static uint32_t
! 378: f_(uint32_t r, uint32_t kl, uint32_t kr)
! 379: {
! 380: uint32_t rl, rr;
! 381: uint32_t s;
! 382: uint32_t p;
! 383:
! 384: etrans1(r, &rl, &rr);
! 385:
! 386: strans(kl ^ rl, kr ^ rr, &s);
! 387:
! 388: p = etrans2(s);
! 389:
! 390: return (p);
! 391: }
! 392:
! 393: /*===========================================================*
! 394: * BASE CRIPTO
! 395: *===========================================================*/
! 396: void
! 397: des_dec_i(
! 398: uint32_t keyl, uint32_t keyr,
! 399: uint32_t msgl, uint32_t msgr,
! 400: uint32_t *el, uint32_t *er)
! 401: {
! 402: uint32_t c, d;
! 403: uint32_t kl, kr;
! 404: uint32_t l, r;
! 405: uint32_t f;
! 406: uint32_t xor;
! 407: int i;
! 408:
! 409: ktrans1(keyl, keyr, &c, &d);
! 410:
! 411: ip(msgl, msgr, &r, &l);
! 412:
! 413: for (i = 0; i < 16; i++) {
! 414: ktrans2(c, d, &kl, &kr);
! 415:
! 416: f = f_(l, kl, kr);
! 417:
! 418: xor = r ^ f;
! 419: r = l;
! 420: l = xor;
! 421:
! 422: c = rshift28(c, i);
! 423: d = rshift28(d, i);
! 424: }
! 425:
! 426: ip_inv(l, r, el, er);
! 427: }
! 428:
! 429:
! 430: void
! 431: des_enc_i(
! 432: uint32_t keyl, uint32_t keyr,
! 433: uint32_t msgl, uint32_t msgr,
! 434: uint32_t *el, uint32_t *er)
! 435: {
! 436: uint32_t c, d;
! 437: uint32_t kl, kr;
! 438: uint32_t l, r;
! 439: uint32_t f;
! 440: uint32_t xor;
! 441: int i;
! 442:
! 443: ktrans1(keyl, keyr, &c, &d);
! 444:
! 445: ip(msgl, msgr, &l, &r);
! 446:
! 447: for (i = 0; i < 16; i++) {
! 448: c = lshift28(c, i);
! 449: d = lshift28(d, i);
! 450:
! 451: ktrans2(c, d, &kl, &kr);
! 452:
! 453: f = f_(r, kl, kr);
! 454:
! 455: xor = l ^ f;
! 456:
! 457: l = r;
! 458: r = xor;
! 459: }
! 460:
! 461: ip_inv(r, l, el, er);
! 462: }
! 463:
! 464: /**
! 465: * input: data: 8 byte
! 466: */
! 467: int
! 468: des_enc_c(const des_key *key, const unsigned char *data, unsigned char *enc)
! 469: {
! 470: uint32_t dl, dr;
! 471: uint32_t el, er;
! 472: int i;
! 473:
! 474: dl = dr = 0;
! 475: for (i = 0; i < 4; i++) {
! 476: dl |= (data[i] & 0xff) << (8 * (3 - i));
! 477: dr |= (data[i + 4] & 0xff) << (8 * (3 - i));
! 478: }
! 479:
! 480: des_enc_i(key->key.ui[0], key->key.ui[1], dl, dr, &el, &er);
! 481:
! 482:
! 483: for (i = 0; i < 4; i++) {
! 484: enc[i] = (el >> (8 * (3 - i))) & 0xff;
! 485: enc[i + 4] = (er >> (8 * (3 - i))) & 0xff;
! 486: }
! 487:
! 488: return (0);
! 489: }
! 490:
! 491:
! 492: /**
! 493: * input: data: 8 byte
! 494: */
! 495: int
! 496: des_dec_c(const des_key *key, const unsigned char *enc, unsigned char *data)
! 497: {
! 498: uint32_t dl, dr;
! 499: uint32_t el, er;
! 500: int i;
! 501:
! 502: dl = dr = 0;
! 503: for (i = 0; i < 4; i++) {
! 504: dl |= (enc[i] & 0xff) << (8 * (3 - i));
! 505: dr |= (enc[i + 4] & 0xff) << (8 * (3 - i));
! 506: }
! 507:
! 508: des_dec_i(key->key.ui[0], key->key.ui[1], dl, dr, &el, &er);
! 509:
! 510:
! 511: for (i = 0; i < 4; i++) {
! 512: data[i] = (el >> (8 * (3 - i))) & 0xff;
! 513: data[i + 4] = (er >> (8 * (3 - i))) & 0xff;
! 514: }
! 515:
! 516: return (0);
! 517: }
! 518:
! 519: /*===========================================================*
! 520: * CRIPTO: length of input data is "64 * n" byte
! 521: *===========================================================*/
! 522: static int
! 523: des_prm_chk(int datalen, int buflen)
! 524: {
! 525: if (datalen % BLOCK != 0)
! 526: return (-1);
! 527: if (buflen < datalen)
! 528: return (-2);
! 529: return (0);
! 530: }
! 531:
! 532:
! 533: int
! 534: des_enc_ecb(const des_key *key, int len, const unsigned char *data, unsigned char *buf)
! 535: {
! 536: int ret;
! 537:
! 538: ret = crypt_ecb((void *)key, BLOCK, len, data, buf, (void *)des_enc_c);
! 539:
! 540: return (ret);
! 541: }
! 542:
! 543:
! 544: int
! 545: des_dec_ecb(const des_key *key, int len, const unsigned char *enc, unsigned char *data)
! 546: {
! 547: int ret;
! 548:
! 549: ret = crypt_ecb((void *)key, BLOCK, len, enc, data, (void *)des_dec_c);
! 550:
! 551: return (ret);
! 552: }
! 553:
! 554:
! 555:
! 556: int
! 557: des_enc_cbc(const des_key *key, const unsigned char *iv, int len,
! 558: const unsigned char *data, unsigned char *buf)
! 559: {
! 560: int ret;
! 561:
! 562: ret = crypt_enc_cbc((void *)key, BLOCK, iv, len, data, buf, (void *)des_enc_c);
! 563:
! 564: return (ret);
! 565: }
! 566:
! 567:
! 568: int
! 569: des_dec_cbc(const des_key *key, const unsigned char *iv, int len,
! 570: const unsigned char *data, unsigned char *buf)
! 571: {
! 572: int ret;
! 573:
! 574: ret = crypt_dec_cbc((void *)key, BLOCK, iv, len, data, buf, (void *)des_dec_c);
! 575:
! 576: return (ret);
! 577: }
! 578:
! 579:
! 580: int
! 581: des_enc_cfb(const des_key *key, int bit,
! 582: const unsigned char *iv, int len,
! 583: const unsigned char *data, unsigned char *buf)
! 584: {
! 585: int ret;
! 586:
! 587: ret = crypt_cfb((void *)key, 0, bit, BLOCK, iv, len, data, buf, (void *)des_enc_c);
! 588:
! 589: return (ret);
! 590: }
! 591:
! 592: int
! 593: des_dec_cfb(const des_key *key, int bit,
! 594: const unsigned char *iv, int len,
! 595: const unsigned char *data, unsigned char *buf)
! 596: {
! 597: int ret;
! 598:
! 599: ret = crypt_cfb((void *)key, 1, bit, BLOCK, iv, len, data, buf, (void *)des_enc_c);
! 600:
! 601: return (ret);
! 602: }
! 603:
! 604:
! 605: int
! 606: des_ofb(const des_key *key, int bit,
! 607: const unsigned char *iv, int len,
! 608: const unsigned char *data,
! 609: unsigned char *buf)
! 610: {
! 611: int ret;
! 612: ret = crypt_ofb((void *)key, bit, BLOCK, iv, len, data, buf, (void *)des_enc_c);
! 613:
! 614: return (ret);
! 615: }
! 616:
! 617:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>