modes_test.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
  2. /* SPDX-License-Identifier: Unlicense */
  3. /* test CFB/OFB/CBC modes */
  4. #include <tomcrypt_test.h>
  5. #ifdef LTC_CFB_MODE
  6. static const struct {
  7. int width;
  8. const char *key, *iv, *pt, *ct;
  9. } cfb_testvectors[] = {
  10. {
  11. 1,
  12. "2b7e151628aed2a6abf7158809cf4f3c",
  13. "000102030405060708090a0b0c0d0e0f",
  14. "6bc1",
  15. "68b3",
  16. },
  17. {
  18. 8,
  19. "2b7e151628aed2a6abf7158809cf4f3c",
  20. "000102030405060708090a0b0c0d0e0f",
  21. "6bc1b3e22e409f96e93d7e117393172aae2d",
  22. "3b79424c9c0dd436bace9e0ed4586a4f32b9",
  23. },
  24. };
  25. #endif
  26. int modes_test(void)
  27. {
  28. int ret = CRYPT_NOP;
  29. #ifdef LTC_CBC_MODE
  30. symmetric_CBC cbc;
  31. #endif
  32. #ifdef LTC_OFB_MODE
  33. symmetric_OFB ofb;
  34. #endif
  35. #ifdef LTC_CFB_MODE
  36. symmetric_CFB cfb;
  37. unsigned char tmp2[64];
  38. unsigned long n;
  39. #endif
  40. #if defined(LTC_CBC_MODE) || defined(LTC_CFB_MODE) || defined(LTC_OFB_MODE)
  41. unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16];
  42. int cipher_idx;
  43. unsigned long l;
  44. /* make a random pt, key and iv */
  45. ENSURE(yarrow_read(pt, 64, &yarrow_prng) == 64);
  46. ENSURE(yarrow_read(key, 16, &yarrow_prng) == 16);
  47. ENSURE(yarrow_read(iv, 16, &yarrow_prng) == 16);
  48. /* get idx of AES handy */
  49. cipher_idx = find_cipher("aes");
  50. if (cipher_idx == -1) {
  51. fprintf(stderr, "test requires AES");
  52. return 1;
  53. }
  54. #endif
  55. #ifdef LTC_F8_MODE
  56. DO(ret = f8_test_mode());
  57. #endif
  58. #ifdef LTC_LRW_MODE
  59. DO(ret = lrw_test());
  60. #endif
  61. #ifdef LTC_CBC_MODE
  62. /* test CBC mode */
  63. /* encode the block */
  64. DO(ret = cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
  65. l = sizeof(iv2);
  66. DO(ret = cbc_getiv(iv2, &l, &cbc));
  67. if (l != 16 || memcmp(iv2, iv, 16)) {
  68. fprintf(stderr, "cbc_getiv failed");
  69. return 1;
  70. }
  71. DO(ret = cbc_encrypt(pt, ct, 64, &cbc));
  72. /* decode the block */
  73. DO(ret = cbc_setiv(iv2, l, &cbc));
  74. zeromem(tmp, sizeof(tmp));
  75. DO(ret = cbc_decrypt(ct, tmp, 64, &cbc));
  76. if (memcmp(tmp, pt, 64) != 0) {
  77. fprintf(stderr, "CBC failed");
  78. return 1;
  79. }
  80. #endif
  81. #ifdef LTC_CFB_MODE
  82. /* test CFB mode */
  83. /* encode the block */
  84. DO(ret = cfb_start(cipher_idx, iv, key, 16, 0, &cfb));
  85. l = sizeof(iv2);
  86. DO(ret = cfb_getiv(iv2, &l, &cfb));
  87. /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */
  88. ENSURE(l == 16);
  89. DO(ret = cfb_encrypt(pt, ct, 64, &cfb));
  90. /* decode the block */
  91. DO(ret = cfb_setiv(iv, l, &cfb));
  92. zeromem(tmp, sizeof(tmp));
  93. DO(ret = cfb_decrypt(ct, tmp, 64, &cfb));
  94. COMPARE_TESTVECTOR(tmp, 64, pt, 64, "cfb128-enc-dec", 0);
  95. cfb_done(&cfb);
  96. XMEMSET(&cfb, 0, sizeof(cfb));
  97. #define b16(e, w) do { \
  98. l = sizeof(w); \
  99. DO(base16_decode(e . w, XSTRLEN(e . w), w, &l)); \
  100. } while(0)
  101. for (n = 0; n < sizeof(cfb_testvectors)/sizeof(cfb_testvectors[0]); ++n) {
  102. b16(cfb_testvectors[n], key);
  103. b16(cfb_testvectors[n], iv);
  104. b16(cfb_testvectors[n], pt);
  105. b16(cfb_testvectors[n], ct);
  106. DO(cfb_start_ex(cipher_idx, iv, key, 16, 0, cfb_testvectors[n].width, &cfb));
  107. l = sizeof(iv2);
  108. DO(cfb_getiv(iv2, &l, &cfb));
  109. ENSURE(l == 16);
  110. DO(ret = cfb_encrypt(pt, tmp, 2, &cfb));
  111. COMPARE_TESTVECTOR(tmp, 2, ct, 2, "cfb-enc", n);
  112. DO(cfb_setiv(iv2, l, &cfb));
  113. DO(ret = cfb_decrypt(tmp, tmp2, 2, &cfb));
  114. COMPARE_TESTVECTOR(tmp2, 2, pt, 2, "cfb-dec", n);
  115. }
  116. #endif
  117. #ifdef LTC_OFB_MODE
  118. /* test OFB mode */
  119. /* encode the block */
  120. DO(ret = ofb_start(cipher_idx, iv, key, 16, 0, &ofb));
  121. l = sizeof(iv2);
  122. DO(ret = ofb_getiv(iv2, &l, &ofb));
  123. if (l != 16 || memcmp(iv2, iv, 16)) {
  124. fprintf(stderr, "ofb_getiv failed");
  125. return 1;
  126. }
  127. DO(ret = ofb_encrypt(pt, ct, 64, &ofb));
  128. /* decode the block */
  129. DO(ret = ofb_setiv(iv2, l, &ofb));
  130. zeromem(tmp, sizeof(tmp));
  131. DO(ret = ofb_decrypt(ct, tmp, 64, &ofb));
  132. if (memcmp(tmp, pt, 64) != 0) {
  133. fprintf(stderr, "OFB failed");
  134. return 1;
  135. }
  136. #endif
  137. #if defined(LTC_CTR_MODE) && defined(LTC_RIJNDAEL)
  138. DO(ret = ctr_test());
  139. #endif
  140. #ifdef LTC_XTS_MODE
  141. DO(ret = xts_test());
  142. #endif
  143. return 0;
  144. }