rijndael-api-fst.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:14k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * rijndael-api-fst.c   v2.4   April '2000
  3.  *
  4.  * Optimised ANSI C code
  5.  *
  6.  * authors: v1.0: Antoon Bosselaers
  7.  *          v2.0: Vincent Rijmen
  8.  *          v2.1: Vincent Rijmen
  9.  *          v2.2: Vincent Rijmen
  10.  *          v2.3: Paulo Barreto
  11.  *          v2.4: Vincent Rijmen
  12.  *
  13.  * This code is placed in the public domain.
  14.  */
  15. #include <assert.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "rijndael-alg-fst.h"
  19. #include "rijndael-api-fst.h"
  20. int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) {
  21. word8 k[MAXKC][4];
  22. int i;
  23. char *keyMat;
  24. if (key == NULL) {
  25. return BAD_KEY_INSTANCE;
  26. }
  27. if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
  28. key->direction = direction;
  29. } else {
  30. return BAD_KEY_DIR;
  31. }
  32. if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 
  33. key->keyLen = keyLen;
  34. } else {
  35. return BAD_KEY_MAT;
  36. }
  37. if (keyMaterial != NULL) {
  38. strncpy(key->keyMaterial, keyMaterial, keyLen/4);
  39. }
  40. key->ROUNDS = keyLen/32 + 6;
  41. /* initialize key schedule: */
  42. keyMat = key->keyMaterial;
  43. #ifndef BINARY_KEY_MATERIAL
  44.   for (i = 0; i < key->keyLen/8; i++) {
  45. int t, j;
  46. t = *keyMat++;
  47. if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
  48. else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; 
  49. else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; 
  50. else return BAD_KEY_MAT;
  51. t = *keyMat++;
  52. if ((t >= '0') && (t <= '9')) j ^= (t - '0');
  53. else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); 
  54. else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); 
  55. else return BAD_KEY_MAT;
  56. k[i >> 2][i & 3] = (word8)j; 
  57. }
  58. #else
  59. for (i = 0; i < key->keyLen/8; i++) {
  60. k[i >> 2][i & 3] = (word8)keyMat[i]; 
  61. }
  62. #endif /* ?BINARY_KEY_MATERIAL */
  63. rijndaelKeySched(k, key->keySched, key->ROUNDS);
  64. if (direction == DIR_DECRYPT) {
  65. rijndaelKeyEncToDec(key->keySched, key->ROUNDS);
  66. }
  67. return TRUE;
  68. }
  69. int cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
  70. if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
  71. cipher->mode = mode;
  72. } else {
  73. return BAD_CIPHER_MODE;
  74. }
  75. if (IV != NULL) {
  76. #ifndef BINARY_KEY_MATERIAL
  77. int i;
  78.   for (i = 0; i < MAX_IV_SIZE; i++) {
  79. int t, j;
  80. t = IV[2*i];
  81. if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
  82. else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; 
  83. else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; 
  84. else return BAD_CIPHER_INSTANCE;
  85. t = IV[2*i+1];
  86. if ((t >= '0') && (t <= '9')) j ^= (t - '0');
  87. else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); 
  88. else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); 
  89. else return BAD_CIPHER_INSTANCE;
  90. cipher->IV[i] = (word8)j;
  91. }
  92. #else
  93. memcpy(cipher->IV, IV, MAX_IV_SIZE);
  94. #endif /* ?BINARY_KEY_MATERIAL */
  95. } else {
  96. memset(cipher->IV, 0, MAX_IV_SIZE);
  97. }
  98. return TRUE;
  99. }
  100. int blockEncrypt(cipherInstance *cipher, keyInstance *key,
  101. BYTE *input, int inputLen, BYTE *outBuffer) {
  102. int i, k, numBlocks;
  103. word8 block[16], iv[4][4];
  104. if (cipher == NULL ||
  105. key == NULL ||
  106. key->direction == DIR_DECRYPT) {
  107. return BAD_CIPHER_STATE;
  108. }
  109. if (input == NULL || inputLen <= 0) {
  110. return 0; /* nothing to do */
  111. }
  112. numBlocks = inputLen/128;
  113. switch (cipher->mode) {
  114. case MODE_ECB: 
  115. for (i = numBlocks; i > 0; i--) {
  116. rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS);
  117. input += 16;
  118. outBuffer += 16;
  119. }
  120. break;
  121. case MODE_CBC:
  122. ((word32*)block)[0] = ((word32*)cipher->IV)[0] ^ ((word32*)input)[0];
  123. ((word32*)block)[1] = ((word32*)cipher->IV)[1] ^ ((word32*)input)[1];
  124. ((word32*)block)[2] = ((word32*)cipher->IV)[2] ^ ((word32*)input)[2];
  125. ((word32*)block)[3] = ((word32*)cipher->IV)[3] ^ ((word32*)input)[3];
  126. rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
  127. input += 16;
  128. for (i = numBlocks - 1; i > 0; i--) {
  129. ((word32*)block)[0] = ((word32*)outBuffer)[0] ^ ((word32*)input)[0];
  130. ((word32*)block)[1] = ((word32*)outBuffer)[1] ^ ((word32*)input)[1];
  131. ((word32*)block)[2] = ((word32*)outBuffer)[2] ^ ((word32*)input)[2];
  132. ((word32*)block)[3] = ((word32*)outBuffer)[3] ^ ((word32*)input)[3];
  133. outBuffer += 16;
  134. rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
  135. input += 16;
  136. }
  137. break;
  138. case MODE_CFB1:
  139. #if STRICT_ALIGN 
  140. memcpy(iv, cipher->IV, 16); 
  141. #else  /* !STRICT_ALIGN */
  142. *((word32*)iv[0]) = *((word32*)(cipher->IV   ));
  143. *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4));
  144. *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8));
  145. *((word32*)iv[3]) = *((word32*)(cipher->IV+12));
  146. #endif /* ?STRICT_ALIGN */
  147. for (i = numBlocks; i > 0; i--) {
  148. for (k = 0; k < 128; k++) {
  149. *((word32*) block    ) = *((word32*)iv[0]);
  150. *((word32*)(block+ 4)) = *((word32*)iv[1]);
  151. *((word32*)(block+ 8)) = *((word32*)iv[2]);
  152. *((word32*)(block+12)) = *((word32*)iv[3]);
  153. rijndaelEncrypt(block, block, key->keySched, key->ROUNDS);
  154. outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
  155. iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
  156. iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
  157. iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
  158. iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
  159. iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
  160. iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
  161. iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
  162. iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
  163. iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
  164. iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
  165. iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
  166. iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
  167. iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
  168. iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
  169. iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
  170. iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
  171. }
  172. }
  173. break;
  174. default:
  175. return BAD_CIPHER_STATE;
  176. }
  177. return 128*numBlocks;
  178. }
  179. /**
  180.  * Encrypt data partitioned in octets, using RFC 2040-like padding.
  181.  *
  182.  * @param   input           data to be encrypted (octet sequence)
  183.  * @param   inputOctets input length in octets (not bits)
  184.  * @param   outBuffer       encrypted output data
  185.  *
  186.  * @return length in octets (not bits) of the encrypted output buffer.
  187.  */
  188. int padEncrypt(cipherInstance *cipher, keyInstance *key,
  189. BYTE *input, int inputOctets, BYTE *outBuffer) {
  190. int i, numBlocks, padLen;
  191. word8 block[16], *iv;
  192. if (cipher == NULL ||
  193. key == NULL ||
  194. key->direction == DIR_DECRYPT) {
  195. return BAD_CIPHER_STATE;
  196. }
  197. if (input == NULL || inputOctets <= 0) {
  198. return 0; /* nothing to do */
  199. }
  200. numBlocks = inputOctets/16;
  201. switch (cipher->mode) {
  202. case MODE_ECB: 
  203. for (i = numBlocks; i > 0; i--) {
  204. rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS);
  205. input += 16;
  206. outBuffer += 16;
  207. }
  208. padLen = 16 - (inputOctets - 16*numBlocks);
  209. assert(padLen > 0 && padLen <= 16);
  210. memcpy(block, input, 16 - padLen);
  211. memset(block + 16 - padLen, padLen, padLen);
  212. rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
  213. break;
  214. case MODE_CBC:
  215. iv = cipher->IV;
  216. for (i = numBlocks; i > 0; i--) {
  217. ((word32*)block)[0] = ((word32*)input)[0] ^ ((word32*)iv)[0];
  218. ((word32*)block)[1] = ((word32*)input)[1] ^ ((word32*)iv)[1];
  219. ((word32*)block)[2] = ((word32*)input)[2] ^ ((word32*)iv)[2];
  220. ((word32*)block)[3] = ((word32*)input)[3] ^ ((word32*)iv)[3];
  221. rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
  222. iv = outBuffer;
  223. input += 16;
  224. outBuffer += 16;
  225. }
  226. padLen = 16 - (inputOctets - 16*numBlocks);
  227. assert(padLen > 0 && padLen <= 16);
  228. for (i = 0; i < 16 - padLen; i++) {
  229. block[i] = input[i] ^ iv[i];
  230. }
  231. for (i = 16 - padLen; i < 16; i++) {
  232. block[i] = (BYTE)padLen ^ iv[i];
  233. }
  234. rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
  235. break;
  236. default:
  237. return BAD_CIPHER_STATE;
  238. }
  239. return 16*(numBlocks + 1);
  240. }
  241. int blockDecrypt(cipherInstance *cipher, keyInstance *key,
  242. BYTE *input, int inputLen, BYTE *outBuffer) {
  243. int i, k, numBlocks;
  244. word8 block[16], iv[4][4];
  245. if (cipher == NULL ||
  246. key == NULL ||
  247. (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
  248. return BAD_CIPHER_STATE;
  249. }
  250. if (input == NULL || inputLen <= 0) {
  251. return 0; /* nothing to do */
  252. }
  253. numBlocks = inputLen/128;
  254. switch (cipher->mode) {
  255. case MODE_ECB: 
  256. for (i = numBlocks; i > 0; i--) { 
  257. rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS);
  258. input += 16;
  259. outBuffer += 16;
  260. }
  261. break;
  262. case MODE_CBC:
  263. #if STRICT_ALIGN 
  264. memcpy(iv, cipher->IV, 16); 
  265. #else
  266. *((word32*)iv[0]) = *((word32*)(cipher->IV   ));
  267. *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4));
  268. *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8));
  269. *((word32*)iv[3]) = *((word32*)(cipher->IV+12));
  270. #endif
  271. for (i = numBlocks; i > 0; i--) {
  272. rijndaelDecrypt(input, block, key->keySched, key->ROUNDS);
  273. ((word32*)block)[0] ^= *((word32*)iv[0]);
  274. ((word32*)block)[1] ^= *((word32*)iv[1]);
  275. ((word32*)block)[2] ^= *((word32*)iv[2]);
  276. ((word32*)block)[3] ^= *((word32*)iv[3]);
  277. #if STRICT_ALIGN
  278. memcpy(iv, input, 16);
  279. memcpy(outBuf, block, 16);
  280. #else
  281. *((word32*)iv[0]) = ((word32*)input)[0]; ((word32*)outBuffer)[0] = ((word32*)block)[0];
  282. *((word32*)iv[1]) = ((word32*)input)[1]; ((word32*)outBuffer)[1] = ((word32*)block)[1];
  283. *((word32*)iv[2]) = ((word32*)input)[2]; ((word32*)outBuffer)[2] = ((word32*)block)[2];
  284. *((word32*)iv[3]) = ((word32*)input)[3]; ((word32*)outBuffer)[3] = ((word32*)block)[3];
  285. #endif
  286. input += 16;
  287. outBuffer += 16;
  288. }
  289. break;
  290. case MODE_CFB1:
  291. #if STRICT_ALIGN 
  292. memcpy(iv, cipher->IV, 16); 
  293. #else
  294. *((word32*)iv[0]) = *((word32*)(cipher->IV));
  295. *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4));
  296. *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8));
  297. *((word32*)iv[3]) = *((word32*)(cipher->IV+12));
  298. #endif
  299. for (i = numBlocks; i > 0; i--) {
  300. for (k = 0; k < 128; k++) {
  301. *((word32*) block    ) = *((word32*)iv[0]);
  302. *((word32*)(block+ 4)) = *((word32*)iv[1]);
  303. *((word32*)(block+ 8)) = *((word32*)iv[2]);
  304. *((word32*)(block+12)) = *((word32*)iv[3]);
  305. rijndaelEncrypt(block, block, key->keySched, key->ROUNDS);
  306. iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
  307. iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
  308. iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
  309. iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
  310. iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
  311. iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
  312. iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
  313. iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
  314. iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
  315. iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
  316. iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
  317. iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
  318. iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
  319. iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
  320. iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
  321. iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1);
  322. outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
  323. }
  324. }
  325. break;
  326. default:
  327. return BAD_CIPHER_STATE;
  328. }
  329. return 128*numBlocks;
  330. }
  331. int padDecrypt(cipherInstance *cipher, keyInstance *key,
  332. BYTE *input, int inputOctets, BYTE *outBuffer) {
  333. int i, numBlocks, padLen;
  334. word8 block[16];
  335. word32 iv[4];
  336. if (cipher == NULL ||
  337. key == NULL ||
  338. key->direction == DIR_ENCRYPT) {
  339. return BAD_CIPHER_STATE;
  340. }
  341. if (input == NULL || inputOctets <= 0) {
  342. return 0; /* nothing to do */
  343. }
  344. if (inputOctets % 16 != 0) {
  345. return BAD_DATA;
  346. }
  347. numBlocks = inputOctets/16;
  348. switch (cipher->mode) {
  349. case MODE_ECB:
  350. /* all blocks but last */
  351. for (i = numBlocks - 1; i > 0; i--) { 
  352. rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS);
  353. input += 16;
  354. outBuffer += 16;
  355. }
  356. /* last block */
  357. rijndaelDecrypt(input, block, key->keySched, key->ROUNDS);
  358. padLen = block[15];
  359. if (padLen >= 16) {
  360. return BAD_DATA;
  361. }
  362. for (i = 16 - padLen; i < 16; i++) {
  363. if (block[i] != padLen) {
  364. return BAD_DATA;
  365. }
  366. }
  367. memcpy(outBuffer, block, 16 - padLen);
  368. break;
  369. case MODE_CBC:
  370. memcpy(iv, cipher->IV, 16);
  371. /* all blocks but last */
  372. for (i = numBlocks - 1; i > 0; i--) {
  373. rijndaelDecrypt(input, block, key->keySched, key->ROUNDS);
  374. ((word32*)block)[0] ^= iv[0];
  375. ((word32*)block)[1] ^= iv[1];
  376. ((word32*)block)[2] ^= iv[2];
  377. ((word32*)block)[3] ^= iv[3];
  378. memcpy(iv, input, 16);
  379. memcpy(outBuffer, block, 16);
  380. input += 16;
  381. outBuffer += 16;
  382. }
  383. /* last block */
  384. rijndaelDecrypt(input, block, key->keySched, key->ROUNDS);
  385. ((word32*)block)[0] ^= iv[0];
  386. ((word32*)block)[1] ^= iv[1];
  387. ((word32*)block)[2] ^= iv[2];
  388. ((word32*)block)[3] ^= iv[3];
  389. padLen = block[15];
  390. if (padLen <= 0 || padLen > 16) {
  391. return BAD_DATA;
  392. }
  393. for (i = 16 - padLen; i < 16; i++) {
  394. if (block[i] != padLen) {
  395. return BAD_DATA;
  396. }
  397. }
  398. memcpy(outBuffer, block, 16 - padLen);
  399. break;
  400. default:
  401. return BAD_CIPHER_STATE;
  402. }
  403. return 16*numBlocks - padLen;
  404. }
  405. #ifdef INTERMEDIATE_VALUE_KAT
  406. /**
  407.  * cipherUpdateRounds:
  408.  *
  409.  * Encrypts/Decrypts exactly one full block a specified number of rounds.
  410.  * Only used in the Intermediate Value Known Answer Test.
  411.  *
  412.  * Returns:
  413.  * TRUE - on success
  414.  * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized)
  415.  */
  416. int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key,
  417. BYTE *input, int inputLen, BYTE *outBuffer, int rounds) {
  418. int j;
  419. word8 block[4][4];
  420. if (cipher == NULL || key == NULL) {
  421. return BAD_CIPHER_STATE;
  422. }
  423. for (j = 3; j >= 0; j--) {
  424. /* parse input stream into rectangular array */
  425.    *((word32*)block[j]) = *((word32*)(input+4*j));
  426. }
  427. switch (key->direction) {
  428. case DIR_ENCRYPT:
  429. rijndaelEncryptRound(block, key->keySched, key->ROUNDS, rounds);
  430. break;
  431. case DIR_DECRYPT:
  432. rijndaelDecryptRound(block, key->keySched, key->ROUNDS, rounds);
  433. break;
  434. default:
  435. return BAD_KEY_DIR;
  436. for (j = 3; j >= 0; j--) {
  437. /* parse rectangular array into output ciphertext bytes */
  438. *((word32*)(outBuffer+4*j)) = *((word32*)block[j]);
  439. }
  440. return TRUE;
  441. }
  442. #endif /* INTERMEDIATE_VALUE_KAT */