Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

277 Zeilen
9.5 KiB

  1. /* Copyright (c) 2014, Google Inc.
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  14. #include <stdint.h>
  15. #include <string.h>
  16. #include <vector>
  17. #include <openssl/aead.h>
  18. #include <openssl/crypto.h>
  19. #include <openssl/err.h>
  20. #include "../test/file_test.h"
  21. #include "../test/stl_compat.h"
  22. // This program tests an AEAD against a series of test vectors from a file,
  23. // using the FileTest format. As an example, here's a valid test case:
  24. //
  25. // KEY: 5a19f3173586b4c42f8412f4d5a786531b3231753e9e00998aec12fda8df10e4
  26. // NONCE: 978105dfce667bf4
  27. // IN: 6a4583908d
  28. // AD: b654574932
  29. // CT: 5294265a60
  30. // TAG: 1d45758621762e061368e68868e2f929
  31. // EVP_AEAD_CTX lacks a zero state, so it doesn't fit easily into
  32. // ScopedOpenSSLContext.
  33. class EVP_AEAD_CTXScoper {
  34. public:
  35. EVP_AEAD_CTXScoper(EVP_AEAD_CTX *ctx) : ctx_(ctx) {}
  36. ~EVP_AEAD_CTXScoper() {
  37. EVP_AEAD_CTX_cleanup(ctx_);
  38. }
  39. private:
  40. EVP_AEAD_CTX *ctx_;
  41. };
  42. static bool TestAEAD(FileTest *t, void *arg) {
  43. const EVP_AEAD *aead = reinterpret_cast<const EVP_AEAD*>(arg);
  44. std::vector<uint8_t> key, nonce, in, ad, ct, tag;
  45. if (!t->GetBytes(&key, "KEY") ||
  46. !t->GetBytes(&nonce, "NONCE") ||
  47. !t->GetBytes(&in, "IN") ||
  48. !t->GetBytes(&ad, "AD") ||
  49. !t->GetBytes(&ct, "CT") ||
  50. !t->GetBytes(&tag, "TAG")) {
  51. return false;
  52. }
  53. EVP_AEAD_CTX ctx;
  54. if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
  55. key.size(), tag.size(),
  56. evp_aead_seal)) {
  57. t->PrintLine("Failed to init AEAD.");
  58. return false;
  59. }
  60. EVP_AEAD_CTXScoper cleanup(&ctx);
  61. std::vector<uint8_t> out(in.size() + EVP_AEAD_max_overhead(aead));
  62. if (!t->HasAttribute("NO_SEAL")) {
  63. size_t out_len;
  64. if (!EVP_AEAD_CTX_seal(&ctx, bssl::vector_data(&out), &out_len, out.size(),
  65. bssl::vector_data(&nonce), nonce.size(),
  66. bssl::vector_data(&in), in.size(),
  67. bssl::vector_data(&ad), ad.size())) {
  68. t->PrintLine("Failed to run AEAD.");
  69. return false;
  70. }
  71. out.resize(out_len);
  72. if (out.size() != ct.size() + tag.size()) {
  73. t->PrintLine("Bad output length: %u vs %u.", (unsigned)out_len,
  74. (unsigned)(ct.size() + tag.size()));
  75. return false;
  76. }
  77. if (!t->ExpectBytesEqual(bssl::vector_data(&ct), ct.size(),
  78. bssl::vector_data(&out), ct.size()) ||
  79. !t->ExpectBytesEqual(bssl::vector_data(&tag), tag.size(),
  80. bssl::vector_data(&out) + ct.size(), tag.size())) {
  81. return false;
  82. }
  83. } else {
  84. out.resize(ct.size() + tag.size());
  85. memcpy(bssl::vector_data(&out), bssl::vector_data(&ct), ct.size());
  86. memcpy(bssl::vector_data(&out) + ct.size(), bssl::vector_data(&tag),
  87. tag.size());
  88. }
  89. // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
  90. // reset after each operation.
  91. EVP_AEAD_CTX_cleanup(&ctx);
  92. if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
  93. key.size(), tag.size(),
  94. evp_aead_open)) {
  95. t->PrintLine("Failed to init AEAD.");
  96. return false;
  97. }
  98. std::vector<uint8_t> out2(out.size());
  99. size_t out2_len;
  100. int ret = EVP_AEAD_CTX_open(&ctx,
  101. bssl::vector_data(&out2), &out2_len, out2.size(),
  102. bssl::vector_data(&nonce), nonce.size(),
  103. bssl::vector_data(&out), out.size(),
  104. bssl::vector_data(&ad), ad.size());
  105. if (t->HasAttribute("FAILS")) {
  106. if (ret) {
  107. t->PrintLine("Decrypted bad data.");
  108. return false;
  109. }
  110. ERR_clear_error();
  111. return true;
  112. }
  113. if (!ret) {
  114. t->PrintLine("Failed to decrypt.");
  115. return false;
  116. }
  117. out2.resize(out2_len);
  118. if (!t->ExpectBytesEqual(bssl::vector_data(&in), in.size(),
  119. bssl::vector_data(&out2), out2.size())) {
  120. return false;
  121. }
  122. // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
  123. // reset after each operation.
  124. EVP_AEAD_CTX_cleanup(&ctx);
  125. if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
  126. key.size(), tag.size(),
  127. evp_aead_open)) {
  128. t->PrintLine("Failed to init AEAD.");
  129. return false;
  130. }
  131. // Garbage at the end isn't ignored.
  132. out.push_back(0);
  133. out2.resize(out.size());
  134. if (EVP_AEAD_CTX_open(&ctx, bssl::vector_data(&out2), &out2_len, out2.size(),
  135. bssl::vector_data(&nonce), nonce.size(),
  136. bssl::vector_data(&out), out.size(),
  137. bssl::vector_data(&ad), ad.size())) {
  138. t->PrintLine("Decrypted bad data with trailing garbage.");
  139. return false;
  140. }
  141. ERR_clear_error();
  142. // The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
  143. // reset after each operation.
  144. EVP_AEAD_CTX_cleanup(&ctx);
  145. if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
  146. key.size(), tag.size(),
  147. evp_aead_open)) {
  148. t->PrintLine("Failed to init AEAD.");
  149. return false;
  150. }
  151. // Verify integrity is checked.
  152. out[0] ^= 0x80;
  153. out.resize(out.size() - 1);
  154. out2.resize(out.size());
  155. if (EVP_AEAD_CTX_open(&ctx, bssl::vector_data(&out2), &out2_len, out2.size(),
  156. bssl::vector_data(&nonce), nonce.size(),
  157. bssl::vector_data(&out), out.size(),
  158. bssl::vector_data(&ad), ad.size())) {
  159. t->PrintLine("Decrypted bad data with corrupted byte.");
  160. return false;
  161. }
  162. ERR_clear_error();
  163. return true;
  164. }
  165. static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
  166. EVP_AEAD_CTX ctx;
  167. uint8_t key[128];
  168. memset(key, 0, sizeof(key));
  169. const size_t key_len = EVP_AEAD_key_length(aead);
  170. if (key_len > sizeof(key)) {
  171. fprintf(stderr, "Key length of AEAD too long.\n");
  172. return 0;
  173. }
  174. if (EVP_AEAD_CTX_init(&ctx, aead, key, key_len,
  175. 9999 /* a silly tag length to trigger an error */,
  176. NULL /* ENGINE */) != 0) {
  177. fprintf(stderr, "A silly tag length didn't trigger an error!\n");
  178. return 0;
  179. }
  180. /* Running a second, failed _init should not cause a memory leak. */
  181. if (EVP_AEAD_CTX_init(&ctx, aead, key, key_len,
  182. 9999 /* a silly tag length to trigger an error */,
  183. NULL /* ENGINE */) != 0) {
  184. fprintf(stderr, "A silly tag length didn't trigger an error!\n");
  185. return 0;
  186. }
  187. /* Calling _cleanup on an |EVP_AEAD_CTX| after a failed _init should be a
  188. * no-op. */
  189. EVP_AEAD_CTX_cleanup(&ctx);
  190. return 1;
  191. }
  192. struct AEADName {
  193. const char name[40];
  194. const EVP_AEAD *(*func)(void);
  195. };
  196. static const struct AEADName kAEADs[] = {
  197. { "aes-128-gcm", EVP_aead_aes_128_gcm },
  198. { "aes-256-gcm", EVP_aead_aes_256_gcm },
  199. { "chacha20-poly1305", EVP_aead_chacha20_poly1305 },
  200. { "rc4-md5-tls", EVP_aead_rc4_md5_tls },
  201. { "rc4-sha1-tls", EVP_aead_rc4_sha1_tls },
  202. { "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls },
  203. { "aes-128-cbc-sha1-tls-implicit-iv", EVP_aead_aes_128_cbc_sha1_tls_implicit_iv },
  204. { "aes-128-cbc-sha256-tls", EVP_aead_aes_128_cbc_sha256_tls },
  205. { "aes-256-cbc-sha1-tls", EVP_aead_aes_256_cbc_sha1_tls },
  206. { "aes-256-cbc-sha1-tls-implicit-iv", EVP_aead_aes_256_cbc_sha1_tls_implicit_iv },
  207. { "aes-256-cbc-sha256-tls", EVP_aead_aes_256_cbc_sha256_tls },
  208. { "aes-256-cbc-sha384-tls", EVP_aead_aes_256_cbc_sha384_tls },
  209. { "des-ede3-cbc-sha1-tls", EVP_aead_des_ede3_cbc_sha1_tls },
  210. { "des-ede3-cbc-sha1-tls-implicit-iv", EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv },
  211. { "rc4-md5-ssl3", EVP_aead_rc4_md5_ssl3 },
  212. { "rc4-sha1-ssl3", EVP_aead_rc4_sha1_ssl3 },
  213. { "aes-128-cbc-sha1-ssl3", EVP_aead_aes_128_cbc_sha1_ssl3 },
  214. { "aes-256-cbc-sha1-ssl3", EVP_aead_aes_256_cbc_sha1_ssl3 },
  215. { "des-ede3-cbc-sha1-ssl3", EVP_aead_des_ede3_cbc_sha1_ssl3 },
  216. { "aes-128-key-wrap", EVP_aead_aes_128_key_wrap },
  217. { "aes-256-key-wrap", EVP_aead_aes_256_key_wrap },
  218. { "aes-128-ctr-hmac-sha256", EVP_aead_aes_128_ctr_hmac_sha256 },
  219. { "aes-256-ctr-hmac-sha256", EVP_aead_aes_256_ctr_hmac_sha256 },
  220. { "", NULL },
  221. };
  222. int main(int argc, char **argv) {
  223. CRYPTO_library_init();
  224. if (argc != 3) {
  225. fprintf(stderr, "%s <aead> <test file.txt>\n", argv[0]);
  226. return 1;
  227. }
  228. const EVP_AEAD *aead;
  229. for (unsigned i = 0;; i++) {
  230. const struct AEADName &aead_name = kAEADs[i];
  231. if (aead_name.func == NULL) {
  232. fprintf(stderr, "Unknown AEAD: %s\n", argv[1]);
  233. return 2;
  234. }
  235. if (strcmp(aead_name.name, argv[1]) == 0) {
  236. aead = aead_name.func();
  237. break;
  238. }
  239. }
  240. if (!TestCleanupAfterInitFailure(aead)) {
  241. return 1;
  242. }
  243. return FileTestMain(TestAEAD, const_cast<EVP_AEAD*>(aead), argv[2]);
  244. }