padding_test.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. */
  9. #include <tomcrypt_test.h>
  10. #ifdef LTC_PADDING
  11. typedef struct padding_testcase_ padding_testcase;
  12. typedef int (*cmp_padding_testcase)(const padding_testcase*, const unsigned char*, unsigned long);
  13. struct padding_testcase_ {
  14. unsigned long is, should, max, mode;
  15. const char* name;
  16. cmp_padding_testcase cmp;
  17. };
  18. #define EQ(a, b) _eq((a), (b), #a, #b)
  19. static int _eq(unsigned long a, unsigned long b, const char* _a, const char* _b)
  20. {
  21. if (a == b) return CRYPT_OK;
  22. #if defined(LTC_TEST) && defined(LTC_TEST_DBG)
  23. else fprintf(stderr, "'%s == %s' failed, %lu is not equal to %lu\n", _a, _b, a, b);
  24. #else
  25. LTC_UNUSED_PARAM(_a);
  26. LTC_UNUSED_PARAM(_b);
  27. #endif
  28. return CRYPT_FAIL_TESTVECTOR;
  29. }
  30. static int _cmp_pkcs7(const padding_testcase* t, const unsigned char* p, unsigned long len)
  31. {
  32. unsigned long n, diff = len - t->is;
  33. DOX(EQ(len, t->should), t->name);
  34. for (n = len - diff; n < len; ++n) {
  35. DOX(EQ(p[n], diff), t->name);
  36. }
  37. return CRYPT_OK;
  38. }
  39. #ifdef LTC_RNG_GET_BYTES
  40. static int _cmp_iso_10126(const padding_testcase* t, const unsigned char* p, unsigned long len)
  41. {
  42. LTC_UNUSED_PARAM(p);
  43. if (len < t->should || len > t->max) {
  44. #if defined(LTC_TEST) && defined(LTC_TEST_DBG)
  45. fprintf(stderr, "(%lu < %lu || %lu > %lu) failed, %s\n", len, t->should, len, t->max, t->name);
  46. #endif
  47. return CRYPT_FAIL_TESTVECTOR;
  48. }
  49. DOX(EQ(p[len - 1], len - t->is), t->name);
  50. return CRYPT_OK;
  51. }
  52. #endif
  53. static int _cmp_x923(const padding_testcase* t, const unsigned char* p, unsigned long len)
  54. {
  55. unsigned long n, diff = len - t->is;
  56. DOX(EQ(len, t->should), t->name);
  57. for (n = len - diff; n < len - 1; ++n) {
  58. DOX(EQ(p[n], 0x0), t->name);
  59. }
  60. DOX(EQ(p[len - 1], diff), t->name);
  61. return CRYPT_OK;
  62. }
  63. static int _cmp_oaz(const padding_testcase* t, const unsigned char* p, unsigned long len)
  64. {
  65. unsigned long n, diff = len - t->is;
  66. DOX(EQ(len, t->should), t->name);
  67. n = len - diff;
  68. DOX(EQ(p[n], 0x80), t->name);
  69. n++;
  70. for (; n < len; ++n) {
  71. DOX(EQ(p[n], 0x0), t->name);
  72. }
  73. return CRYPT_OK;
  74. }
  75. static int _cmp_zero(const padding_testcase* t, const unsigned char* p, unsigned long len)
  76. {
  77. unsigned long n, diff = len - t->is;
  78. DOX(EQ(len, t->should), t->name);
  79. for (n = len - diff; n < len; ++n) {
  80. DOX(EQ(p[n], 0x0), t->name);
  81. }
  82. return CRYPT_OK;
  83. }
  84. static int _padding_testrun(const padding_testcase* t)
  85. {
  86. unsigned long len;
  87. unsigned char buf[1024];
  88. len = sizeof(buf);
  89. XMEMSET(buf, 0xAA, t->is);
  90. DO(padding_pad(buf, t->is, &len, t->mode));
  91. DO(t->cmp(t, buf, len));
  92. DO(padding_depad(buf, &len, t->mode));
  93. DO(EQ(len, t->is));
  94. return CRYPT_OK;
  95. }
  96. int padding_test(void)
  97. {
  98. const padding_testcase cases[] = {
  99. { 0, 16, 0, LTC_PAD_PKCS7 | 16, "0-pkcs7", _cmp_pkcs7 },
  100. { 1, 16, 0, LTC_PAD_PKCS7 | 16, "1-pkcs7", _cmp_pkcs7 },
  101. { 15, 16, 0, LTC_PAD_PKCS7 | 16, "15-pkcs7", _cmp_pkcs7 },
  102. { 16, 32, 0, LTC_PAD_PKCS7 | 16, "16-pkcs7", _cmp_pkcs7 },
  103. { 255, 256, 0, LTC_PAD_PKCS7 | 16, "255-pkcs7", _cmp_pkcs7 },
  104. { 256, 272, 0, LTC_PAD_PKCS7 | 16, "256-pkcs7", _cmp_pkcs7 },
  105. #ifdef LTC_RNG_GET_BYTES
  106. { 0, 16, 256, LTC_PAD_ISO_10126 | 16, "0-rand", _cmp_iso_10126 },
  107. { 1, 16, 272, LTC_PAD_ISO_10126 | 16, "1-rand", _cmp_iso_10126 },
  108. { 15, 16, 272, LTC_PAD_ISO_10126 | 16, "15-rand", _cmp_iso_10126 },
  109. { 16, 32, 288, LTC_PAD_ISO_10126 | 16, "16-rand", _cmp_iso_10126 },
  110. { 255, 256, 512, LTC_PAD_ISO_10126 | 16, "255-rand", _cmp_iso_10126 },
  111. { 256, 272, 528, LTC_PAD_ISO_10126 | 16, "256-rand", _cmp_iso_10126 },
  112. #endif
  113. { 0, 16, 0, LTC_PAD_ANSI_X923 | 16, "0-x923", _cmp_x923 },
  114. { 1, 16, 0, LTC_PAD_ANSI_X923 | 16, "1-x923", _cmp_x923 },
  115. { 15, 16, 0, LTC_PAD_ANSI_X923 | 16, "15-x923", _cmp_x923 },
  116. { 16, 32, 0, LTC_PAD_ANSI_X923 | 16, "16-x923", _cmp_x923 },
  117. { 255, 256, 0, LTC_PAD_ANSI_X923 | 16, "255-x923", _cmp_x923 },
  118. { 256, 272, 0, LTC_PAD_ANSI_X923 | 16, "256-x923", _cmp_x923 },
  119. { 0, 16, 0, LTC_PAD_ONE_AND_ZERO | 16, "0-one-and-zero", _cmp_oaz },
  120. { 1, 16, 0, LTC_PAD_ONE_AND_ZERO | 16, "1-one-and-zero", _cmp_oaz },
  121. { 15, 16, 0, LTC_PAD_ONE_AND_ZERO | 16, "15-one-and-zero", _cmp_oaz },
  122. { 16, 32, 0, LTC_PAD_ONE_AND_ZERO | 16, "16-one-and-zero", _cmp_oaz },
  123. { 255, 256, 0, LTC_PAD_ONE_AND_ZERO | 16, "255-one-and-zero", _cmp_oaz },
  124. { 256, 272, 0, LTC_PAD_ONE_AND_ZERO | 16, "256-one-and-zero", _cmp_oaz },
  125. { 0, 0, 0, LTC_PAD_ZERO | 16, "0-zero", _cmp_zero },
  126. { 1, 16, 0, LTC_PAD_ZERO | 16, "1-zero", _cmp_zero },
  127. { 15, 16, 0, LTC_PAD_ZERO | 16, "15-zero", _cmp_zero },
  128. { 16, 16, 0, LTC_PAD_ZERO | 16, "16-zero", _cmp_zero },
  129. { 255, 256, 0, LTC_PAD_ZERO | 16, "255-zero", _cmp_zero },
  130. { 256, 256, 0, LTC_PAD_ZERO | 16, "256-zero", _cmp_zero },
  131. { 0, 16, 0, LTC_PAD_ZERO_ALWAYS | 16, "0-zero-always", _cmp_zero },
  132. { 1, 16, 0, LTC_PAD_ZERO_ALWAYS | 16, "1-zero-always", _cmp_zero },
  133. { 15, 16, 0, LTC_PAD_ZERO_ALWAYS | 16, "15-zero-always", _cmp_zero },
  134. { 16, 32, 0, LTC_PAD_ZERO_ALWAYS | 16, "16-zero-always", _cmp_zero },
  135. { 255, 256, 0, LTC_PAD_ZERO_ALWAYS | 16, "255-zero-always", _cmp_zero },
  136. { 256, 272, 0, LTC_PAD_ZERO_ALWAYS | 16, "256-zero-always", _cmp_zero },
  137. };
  138. unsigned i;
  139. /* Examples from https://en.wikipedia.org/w/index.php?title=Padding_(cryptography)&oldid=823057951#Byte_padding */
  140. const struct {
  141. unsigned char data[16];
  142. unsigned long len;
  143. unsigned long mode;
  144. } tv[] = {
  145. { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04, 0x04, 0x04, 0x04 }, 12, LTC_PAD_PKCS7 | 16 },
  146. { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x00, 0x00, 0x00, 0x04 }, 12, LTC_PAD_ANSI_X923 | 16 },
  147. #ifdef LTC_RNG_GET_BYTES
  148. { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x81, 0xA6, 0x23, 0x04 }, 12, LTC_PAD_ISO_10126 | 16 },
  149. #endif
  150. { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x80, 0x00, 0x00, 0x00 }, 12, LTC_PAD_ONE_AND_ZERO | 16 },
  151. { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x80 }, 15, LTC_PAD_ONE_AND_ZERO | 16 },
  152. { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x00, 0x00, 0x00, 0x00 }, 12, LTC_PAD_ZERO | 16 },
  153. };
  154. /* we need a big buffer like that as LTC_PAD_ISO_10126
  155. * is allowed to add 1-255 bytes of padding
  156. */
  157. unsigned char buf[256 + 16];
  158. unsigned long l;
  159. for (i = 0; i < sizeof(cases)/sizeof(cases[0]); ++i) {
  160. DOX(_padding_testrun(&cases[i]), cases[i].name);
  161. }
  162. for (i = 0; i < sizeof(tv)/sizeof(tv[0]); ++i) {
  163. XMEMCPY(buf, tv[i].data, sizeof(tv[i].data));
  164. l = sizeof(tv[i].data);
  165. DO(padding_depad(buf, &l, tv[i].mode));
  166. XMEMSET(buf, 0xDD, 16);
  167. l = sizeof(buf);
  168. DO(padding_pad(buf, tv[i].len, &l, tv[i].mode));
  169. #ifdef LTC_RNG_GET_BYTES
  170. if ((tv[i].mode & LTC_PAD_MASK) != LTC_PAD_ISO_10126)
  171. #endif
  172. {
  173. DO(compare_testvector(tv[i].data, sizeof(tv[i].data), buf, l, "padding fixed TV", i) == 0 ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR);
  174. }
  175. }
  176. return CRYPT_OK;
  177. }
  178. #endif
  179. /* ref: $Format:%D$ */
  180. /* git commit: $Format:%H$ */
  181. /* commit time: $Format:%ai$ */