test-rsa-sig-ver.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. * Testing tool for RSA PKCS #1 v1.5 signature verification
  3. * Copyright (c) 2014, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "crypto/crypto.h"
  11. #include "tls/rsa.h"
  12. #include "tls/asn1.h"
  13. #include "tls/pkcs1.h"
  14. static int cavp_rsa_sig_ver(const char *fname)
  15. {
  16. FILE *f;
  17. int ret = 0;
  18. char buf[15000], *pos, *pos2;
  19. u8 msg[200], n[512], s[512], em[512], e[512];
  20. size_t msg_len = 0, n_len = 0, s_len = 0, em_len, e_len = 0;
  21. size_t tmp_len;
  22. char sha_alg[20];
  23. int ok = 0;
  24. printf("CAVP RSA SigVer test vectors from %s\n", fname);
  25. f = fopen(fname, "r");
  26. if (f == NULL) {
  27. printf("%s does not exist - cannot validate CAVP RSA SigVer test vectors\n",
  28. fname);
  29. return 0;
  30. }
  31. while (fgets(buf, sizeof(buf), f)) {
  32. pos = os_strchr(buf, '=');
  33. if (pos == NULL)
  34. continue;
  35. pos2 = pos - 1;
  36. while (pos2 >= buf && *pos2 == ' ')
  37. *pos2-- = '\0';
  38. *pos++ = '\0';
  39. while (*pos == ' ')
  40. *pos++ = '\0';
  41. pos2 = os_strchr(pos, '\r');
  42. if (!pos2)
  43. pos2 = os_strchr(pos, '\n');
  44. if (pos2)
  45. *pos2 = '\0';
  46. else
  47. pos2 = pos + os_strlen(pos);
  48. if (os_strcmp(buf, "SHAAlg") == 0) {
  49. os_strlcpy(sha_alg, pos, sizeof(sha_alg));
  50. } else if (os_strcmp(buf, "Msg") == 0) {
  51. tmp_len = os_strlen(pos);
  52. if (tmp_len > sizeof(msg) * 2) {
  53. printf("Too long Msg\n");
  54. fclose(f);
  55. return -1;
  56. }
  57. msg_len = tmp_len / 2;
  58. if (hexstr2bin(pos, msg, msg_len) < 0) {
  59. printf("Invalid hex string '%s'\n", pos);
  60. ret++;
  61. break;
  62. }
  63. } else if (os_strcmp(buf, "n") == 0) {
  64. tmp_len = os_strlen(pos);
  65. if (tmp_len > sizeof(n) * 2) {
  66. printf("Too long n\n");
  67. fclose(f);
  68. return -1;
  69. }
  70. n_len = tmp_len / 2;
  71. if (hexstr2bin(pos, n, n_len) < 0) {
  72. printf("Invalid hex string '%s'\n", pos);
  73. ret++;
  74. break;
  75. }
  76. } else if (os_strcmp(buf, "e") == 0) {
  77. tmp_len = os_strlen(pos);
  78. if (tmp_len > sizeof(e) * 2) {
  79. printf("Too long e\n");
  80. fclose(f);
  81. return -1;
  82. }
  83. e_len = tmp_len / 2;
  84. if (hexstr2bin(pos, e, e_len) < 0) {
  85. printf("Invalid hex string '%s'\n", pos);
  86. ret++;
  87. break;
  88. }
  89. } else if (os_strcmp(buf, "S") == 0) {
  90. tmp_len = os_strlen(pos);
  91. if (tmp_len > sizeof(s) * 2) {
  92. printf("Too long S\n");
  93. fclose(f);
  94. return -1;
  95. }
  96. s_len = tmp_len / 2;
  97. if (hexstr2bin(pos, s, s_len) < 0) {
  98. printf("Invalid hex string '%s'\n", pos);
  99. ret++;
  100. break;
  101. }
  102. } else if (os_strncmp(buf, "EM", 2) == 0) {
  103. tmp_len = os_strlen(pos);
  104. if (tmp_len > sizeof(em) * 2) {
  105. fclose(f);
  106. return -1;
  107. }
  108. em_len = tmp_len / 2;
  109. if (hexstr2bin(pos, em, em_len) < 0) {
  110. printf("Invalid hex string '%s'\n", pos);
  111. ret++;
  112. break;
  113. }
  114. } else if (os_strcmp(buf, "Result") == 0) {
  115. const u8 *addr[1];
  116. size_t len[1];
  117. struct crypto_public_key *pk;
  118. int res;
  119. u8 hash[32];
  120. size_t hash_len;
  121. const struct asn1_oid *alg;
  122. addr[0] = msg;
  123. len[0] = msg_len;
  124. if (os_strcmp(sha_alg, "SHA1") == 0) {
  125. if (sha1_vector(1, addr, len, hash) < 0) {
  126. fclose(f);
  127. return -1;
  128. }
  129. hash_len = 20;
  130. alg = &asn1_sha1_oid;
  131. } else if (os_strcmp(sha_alg, "SHA256") == 0) {
  132. if (sha256_vector(1, addr, len, hash) < 0) {
  133. fclose(f);
  134. return -1;
  135. }
  136. hash_len = 32;
  137. alg = &asn1_sha256_oid;
  138. } else {
  139. continue;
  140. }
  141. printf("\nExpected result: %s\n", pos);
  142. wpa_hexdump(MSG_INFO, "Hash(Msg)", hash, hash_len);
  143. pk = crypto_public_key_import_parts(n, n_len,
  144. e, e_len);
  145. if (pk == NULL) {
  146. printf("Failed to import public key\n");
  147. ret++;
  148. continue;
  149. }
  150. res = pkcs1_v15_sig_ver(pk, s, s_len, alg,
  151. hash, hash_len);
  152. crypto_public_key_free(pk);
  153. if ((*pos == 'F' && !res) || (*pos != 'F' && res)) {
  154. printf("FAIL\n");
  155. ret++;
  156. continue;
  157. }
  158. printf("PASS\n");
  159. ok++;
  160. }
  161. }
  162. fclose(f);
  163. if (ret)
  164. printf("Test case failed\n");
  165. else
  166. printf("%d test vectors OK\n", ok);
  167. return ret;
  168. }
  169. int main(int argc, char *argv[])
  170. {
  171. int ret = 0;
  172. wpa_debug_level = 0;
  173. if (cavp_rsa_sig_ver("CAVP/SigVer15_186-3.rsp"))
  174. ret++;
  175. if (cavp_rsa_sig_ver("CAVP/SigVer15EMTest.txt"))
  176. ret++;
  177. return ret;
  178. }