blowfish.c

来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 542 行 · 第 1/2 页

C
542
字号
        0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL,        0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL,        0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL,        0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL,        0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL,        0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL,        0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL,        0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL,        0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL,        0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL,        0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL,        0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL,        0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL,        0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL,        0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL,        0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL,        0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL,        0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL,        0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL,        0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL  }};int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,                   symmetric_key *skey){   ulong32 x, y, z, A;   unsigned char B[8];   _ARGCHK(key != NULL);   _ARGCHK(skey != NULL);   /* check key length */   if (keylen < 8 || keylen > 56) {      return CRYPT_INVALID_KEYSIZE;   }   /* check rounds */   if (num_rounds != 0 && num_rounds != 16) {      return CRYPT_INVALID_ROUNDS;   }      /* load in key bytes (Supplied by David Hopwood) */   for (x = y = 0; x < 18; x++) {       A = 0;       for (z = 0; z < 4; z++) {           A = (A << 8) | ((ulong32)key[y++] & 255);           if (y == (ulong32)keylen) {               y = 0;            }       }       skey->blowfish.K[x] = ORIG_P[x] ^ A;   }   /* copy sboxes */   for (x = 0; x < 4; x++) {       for (y = 0; y < 256; y++) {           skey->blowfish.S[x][y] = ORIG_S[x][y];       }   }   /* encrypt K array */   for (x = 0; x < 8; x++) {       B[x] = 0;   }      for (x = 0; x < 18; x += 2) {       /* encrypt it */       blowfish_ecb_encrypt(B, B, skey);       /* copy it */       LOAD32H(skey->blowfish.K[x], &B[0]);       LOAD32H(skey->blowfish.K[x+1], &B[4]);   }   /* encrypt S array */   for (x = 0; x < 4; x++) {       for (y = 0; y < 256; y += 2) {          /* encrypt it */          blowfish_ecb_encrypt(B, B, skey);          /* copy it */          LOAD32H(skey->blowfish.S[x][y], &B[0]);          LOAD32H(skey->blowfish.S[x][y+1], &B[4]);       }   }#ifdef CLEAN_STACK   zeromem(B, sizeof(B));#endif   return CRYPT_OK;}#ifndef __GNUC__#define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)]#else#define F(x) ((key->blowfish.S[0][byte(x,3)] + key->blowfish.S[1][byte(x,2)]) ^ key->blowfish.S[2][byte(x,1)]) + key->blowfish.S[3][byte(x,0)]#endif#ifdef CLEAN_STACKstatic void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)#elsevoid blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)#endif{   ulong32 L, R;   int r;#ifndef __GNUC__   ulong32 *S1, *S2, *S3, *S4;#endif    _ARGCHK(pt != NULL);    _ARGCHK(ct != NULL);    _ARGCHK(key != NULL);#ifndef __GNUC__    S1 = key->blowfish.S[0];    S2 = key->blowfish.S[1];    S3 = key->blowfish.S[2];    S4 = key->blowfish.S[3];#endif   /* load it */   LOAD32H(L, &pt[0]);   LOAD32H(R, &pt[4]);   /* do 16 rounds */   for (r = 0; r < 16; ) {      L ^= key->blowfish.K[r++];  R ^= F(L);      R ^= key->blowfish.K[r++];  L ^= F(R);      L ^= key->blowfish.K[r++];  R ^= F(L);      R ^= key->blowfish.K[r++];  L ^= F(R);   }   /* last keying */   R ^= key->blowfish.K[17];   L ^= key->blowfish.K[16];   /* store */   STORE32H(R, &ct[0]);   STORE32H(L, &ct[4]);}#ifdef CLEAN_STACKvoid blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key){    _blowfish_ecb_encrypt(pt, ct, key);    burn_stack(sizeof(ulong32) * 2 + sizeof(int));}#endif#ifdef CLEAN_STACKstatic void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)#elsevoid blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)#endif{   ulong32 L, R;   int r;#ifndef __GNUC__   ulong32 *S1, *S2, *S3, *S4;#endif    _ARGCHK(pt != NULL);    _ARGCHK(ct != NULL);    _ARGCHK(key != NULL);    #ifndef __GNUC__    S1 = key->blowfish.S[0];    S2 = key->blowfish.S[1];    S3 = key->blowfish.S[2];    S4 = key->blowfish.S[3];#endif   /* load it */   LOAD32H(R, &ct[0]);   LOAD32H(L, &ct[4]);   /* undo last keying */   R ^= key->blowfish.K[17];   L ^= key->blowfish.K[16];   /* do 16 rounds */   for (r = 15; r > 0; ) {      L ^= F(R); R ^= key->blowfish.K[r--];      R ^= F(L); L ^= key->blowfish.K[r--];      L ^= F(R); R ^= key->blowfish.K[r--];      R ^= F(L); L ^= key->blowfish.K[r--];   }   /* store */   STORE32H(L, &pt[0]);   STORE32H(R, &pt[4]);}#ifdef CLEAN_STACKvoid blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key){    _blowfish_ecb_decrypt(ct, pt, key);    burn_stack(sizeof(ulong32) * 2 + sizeof(int));}#endifint blowfish_test(void){ #ifndef LTC_TEST    return CRYPT_NOP; #else       int err;   symmetric_key key;   static const struct {          unsigned char key[8], pt[8], ct[8];   } tests[] = {       {           { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},           { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},           { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}       },       {           { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},           { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},           { 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}       },       {           { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},           { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},           { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}       }   };   unsigned char tmp[2][8];   int x, y;   for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {      /* setup key */      if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) {         return err;      }      /* encrypt and decrypt */      blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key);      blowfish_ecb_decrypt(tmp[0], tmp[1], &key);      /* compare */      if ((memcmp(tmp[0], tests[x].ct, 8) != 0) || (memcmp(tmp[1], tests[x].pt, 8) != 0)) {         return CRYPT_FAIL_TESTVECTOR;      }      /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */      for (y = 0; y < 8; y++) tmp[0][y] = 0;      for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key);      for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key);      for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;   }   return CRYPT_OK; #endif}int blowfish_keysize(int *desired_keysize){   _ARGCHK(desired_keysize != NULL);   if (*desired_keysize < 8) {      return CRYPT_INVALID_KEYSIZE;   } else if (*desired_keysize > 56) {      *desired_keysize = 56;   }   return CRYPT_OK;}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?