md2.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /*
  2. * RFC 1115/1319 compliant MD2 implementation
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. /*
  20. * The MD2 algorithm was designed by Ron Rivest in 1989.
  21. *
  22. * http://www.ietf.org/rfc/rfc1115.txt
  23. * http://www.ietf.org/rfc/rfc1319.txt
  24. */
  25. #include "common.h"
  26. #if defined(MBEDTLS_MD2_C)
  27. #include "mbedtls/md2.h"
  28. #include "mbedtls/platform_util.h"
  29. #include "mbedtls/error.h"
  30. #include <string.h>
  31. #include "mbedtls/platform.h"
  32. #if !defined(MBEDTLS_MD2_ALT)
  33. static const unsigned char PI_SUBST[256] =
  34. {
  35. 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
  36. 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
  37. 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
  38. 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
  39. 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
  40. 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
  41. 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
  42. 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
  43. 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
  44. 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
  45. 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
  46. 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
  47. 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
  48. 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
  49. 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
  50. 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
  51. 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
  52. 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
  53. 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
  54. 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
  55. 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
  56. 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
  57. 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
  58. 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
  59. 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
  60. 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
  61. };
  62. void mbedtls_md2_init(mbedtls_md2_context *ctx)
  63. {
  64. memset(ctx, 0, sizeof(mbedtls_md2_context));
  65. }
  66. void mbedtls_md2_free(mbedtls_md2_context *ctx)
  67. {
  68. if (ctx == NULL) {
  69. return;
  70. }
  71. mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md2_context));
  72. }
  73. void mbedtls_md2_clone(mbedtls_md2_context *dst,
  74. const mbedtls_md2_context *src)
  75. {
  76. *dst = *src;
  77. }
  78. /*
  79. * MD2 context setup
  80. */
  81. int mbedtls_md2_starts_ret(mbedtls_md2_context *ctx)
  82. {
  83. memset(ctx->cksum, 0, 16);
  84. memset(ctx->state, 0, 46);
  85. memset(ctx->buffer, 0, 16);
  86. ctx->left = 0;
  87. return 0;
  88. }
  89. #if !defined(MBEDTLS_DEPRECATED_REMOVED)
  90. void mbedtls_md2_starts(mbedtls_md2_context *ctx)
  91. {
  92. mbedtls_md2_starts_ret(ctx);
  93. }
  94. #endif
  95. #if !defined(MBEDTLS_MD2_PROCESS_ALT)
  96. int mbedtls_internal_md2_process(mbedtls_md2_context *ctx)
  97. {
  98. int i, j;
  99. unsigned char t = 0;
  100. for (i = 0; i < 16; i++) {
  101. ctx->state[i + 16] = ctx->buffer[i];
  102. ctx->state[i + 32] =
  103. (unsigned char) (ctx->buffer[i] ^ ctx->state[i]);
  104. }
  105. for (i = 0; i < 18; i++) {
  106. for (j = 0; j < 48; j++) {
  107. ctx->state[j] = (unsigned char)
  108. (ctx->state[j] ^ PI_SUBST[t]);
  109. t = ctx->state[j];
  110. }
  111. t = (unsigned char) (t + i);
  112. }
  113. t = ctx->cksum[15];
  114. for (i = 0; i < 16; i++) {
  115. ctx->cksum[i] = (unsigned char)
  116. (ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t]);
  117. t = ctx->cksum[i];
  118. }
  119. /* Zeroise variables to clear sensitive data from memory. */
  120. mbedtls_platform_zeroize(&t, sizeof(t));
  121. return 0;
  122. }
  123. #if !defined(MBEDTLS_DEPRECATED_REMOVED)
  124. void mbedtls_md2_process(mbedtls_md2_context *ctx)
  125. {
  126. mbedtls_internal_md2_process(ctx);
  127. }
  128. #endif
  129. #endif /* !MBEDTLS_MD2_PROCESS_ALT */
  130. /*
  131. * MD2 process buffer
  132. */
  133. int mbedtls_md2_update_ret(mbedtls_md2_context *ctx,
  134. const unsigned char *input,
  135. size_t ilen)
  136. {
  137. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  138. size_t fill;
  139. while (ilen > 0) {
  140. if (ilen > 16 - ctx->left) {
  141. fill = 16 - ctx->left;
  142. } else {
  143. fill = ilen;
  144. }
  145. memcpy(ctx->buffer + ctx->left, input, fill);
  146. ctx->left += fill;
  147. input += fill;
  148. ilen -= fill;
  149. if (ctx->left == 16) {
  150. ctx->left = 0;
  151. if ((ret = mbedtls_internal_md2_process(ctx)) != 0) {
  152. return ret;
  153. }
  154. }
  155. }
  156. return 0;
  157. }
  158. #if !defined(MBEDTLS_DEPRECATED_REMOVED)
  159. void mbedtls_md2_update(mbedtls_md2_context *ctx,
  160. const unsigned char *input,
  161. size_t ilen)
  162. {
  163. mbedtls_md2_update_ret(ctx, input, ilen);
  164. }
  165. #endif
  166. /*
  167. * MD2 final digest
  168. */
  169. int mbedtls_md2_finish_ret(mbedtls_md2_context *ctx,
  170. unsigned char output[16])
  171. {
  172. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  173. size_t i;
  174. unsigned char x;
  175. x = (unsigned char) (16 - ctx->left);
  176. for (i = ctx->left; i < 16; i++) {
  177. ctx->buffer[i] = x;
  178. }
  179. if ((ret = mbedtls_internal_md2_process(ctx)) != 0) {
  180. return ret;
  181. }
  182. memcpy(ctx->buffer, ctx->cksum, 16);
  183. if ((ret = mbedtls_internal_md2_process(ctx)) != 0) {
  184. return ret;
  185. }
  186. memcpy(output, ctx->state, 16);
  187. return 0;
  188. }
  189. #if !defined(MBEDTLS_DEPRECATED_REMOVED)
  190. void mbedtls_md2_finish(mbedtls_md2_context *ctx,
  191. unsigned char output[16])
  192. {
  193. mbedtls_md2_finish_ret(ctx, output);
  194. }
  195. #endif
  196. #endif /* !MBEDTLS_MD2_ALT */
  197. /*
  198. * output = MD2( input buffer )
  199. */
  200. int mbedtls_md2_ret(const unsigned char *input,
  201. size_t ilen,
  202. unsigned char output[16])
  203. {
  204. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  205. mbedtls_md2_context ctx;
  206. mbedtls_md2_init(&ctx);
  207. if ((ret = mbedtls_md2_starts_ret(&ctx)) != 0) {
  208. goto exit;
  209. }
  210. if ((ret = mbedtls_md2_update_ret(&ctx, input, ilen)) != 0) {
  211. goto exit;
  212. }
  213. if ((ret = mbedtls_md2_finish_ret(&ctx, output)) != 0) {
  214. goto exit;
  215. }
  216. exit:
  217. mbedtls_md2_free(&ctx);
  218. return ret;
  219. }
  220. #if !defined(MBEDTLS_DEPRECATED_REMOVED)
  221. void mbedtls_md2(const unsigned char *input,
  222. size_t ilen,
  223. unsigned char output[16])
  224. {
  225. mbedtls_md2_ret(input, ilen, output);
  226. }
  227. #endif
  228. #if defined(MBEDTLS_SELF_TEST)
  229. /*
  230. * RFC 1319 test vectors
  231. */
  232. static const unsigned char md2_test_str[7][81] =
  233. {
  234. { "" },
  235. { "a" },
  236. { "abc" },
  237. { "message digest" },
  238. { "abcdefghijklmnopqrstuvwxyz" },
  239. { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
  240. { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
  241. };
  242. static const size_t md2_test_strlen[7] =
  243. {
  244. 0, 1, 3, 14, 26, 62, 80
  245. };
  246. static const unsigned char md2_test_sum[7][16] =
  247. {
  248. { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
  249. 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
  250. { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
  251. 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
  252. { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
  253. 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
  254. { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
  255. 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
  256. { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
  257. 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
  258. { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
  259. 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
  260. { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
  261. 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
  262. };
  263. /*
  264. * Checkup routine
  265. */
  266. int mbedtls_md2_self_test(int verbose)
  267. {
  268. int i, ret = 0;
  269. unsigned char md2sum[16];
  270. for (i = 0; i < 7; i++) {
  271. if (verbose != 0) {
  272. mbedtls_printf(" MD2 test #%d: ", i + 1);
  273. }
  274. ret = mbedtls_md2_ret(md2_test_str[i], md2_test_strlen[i], md2sum);
  275. if (ret != 0) {
  276. goto fail;
  277. }
  278. if (memcmp(md2sum, md2_test_sum[i], 16) != 0) {
  279. ret = 1;
  280. goto fail;
  281. }
  282. if (verbose != 0) {
  283. mbedtls_printf("passed\n");
  284. }
  285. }
  286. if (verbose != 0) {
  287. mbedtls_printf("\n");
  288. }
  289. return 0;
  290. fail:
  291. if (verbose != 0) {
  292. mbedtls_printf("failed\n");
  293. }
  294. return ret;
  295. }
  296. #endif /* MBEDTLS_SELF_TEST */
  297. #endif /* MBEDTLS_MD2_C */