provider.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. /*
  2. * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. * https://www.openssl.org/source/license.html
  8. * or in the file LICENSE in the source distribution.
  9. */
  10. #include <string.h>
  11. #include <openssl/types.h>
  12. #include <openssl/crypto.h>
  13. #include <openssl/core_names.h>
  14. #include <openssl/kdf.h>
  15. #include <openssl/evp.h>
  16. #include <openssl/provider.h>
  17. #include "fuzzer.h"
  18. #define DEFINE_ALGORITHMS(name, evp) DEFINE_STACK_OF(evp) \
  19. static int cmp_##evp(const evp *const *a, const evp *const *b); \
  20. static void collect_##evp(evp *obj, void *stack); \
  21. static void init_##name(OSSL_LIB_CTX *libctx); \
  22. static void cleanup_##name(void); \
  23. static STACK_OF(evp) *name##_collection; \
  24. static int cmp_##evp(const evp *const *a, const evp *const *b) \
  25. { \
  26. return strcmp(OSSL_PROVIDER_get0_name(evp##_get0_provider(*a)), \
  27. OSSL_PROVIDER_get0_name(evp##_get0_provider(*b))); \
  28. } \
  29. static void collect_##evp(evp *obj, void *stack) \
  30. { \
  31. STACK_OF(evp) *obj_stack = stack; \
  32. \
  33. if (sk_##evp##_push(obj_stack, obj) > 0) \
  34. evp##_up_ref(obj); \
  35. } \
  36. static void init_##name(OSSL_LIB_CTX *libctx) \
  37. { \
  38. name##_collection = sk_##evp##_new(cmp_##evp); \
  39. evp##_do_all_provided(libctx, collect_##evp, name##_collection); \
  40. } \
  41. static void cleanup_##name(void) \
  42. { \
  43. sk_##evp##_pop_free(name##_collection, evp##_free); \
  44. }
  45. DEFINE_ALGORITHMS(digests, EVP_MD)
  46. DEFINE_ALGORITHMS(kdf, EVP_KDF)
  47. DEFINE_ALGORITHMS(cipher, EVP_CIPHER)
  48. DEFINE_ALGORITHMS(kem, EVP_KEM)
  49. DEFINE_ALGORITHMS(keyexch, EVP_KEYEXCH)
  50. DEFINE_ALGORITHMS(rand, EVP_RAND)
  51. DEFINE_ALGORITHMS(mac, EVP_MAC)
  52. DEFINE_ALGORITHMS(keymgmt, EVP_KEYMGMT)
  53. DEFINE_ALGORITHMS(signature, EVP_SIGNATURE)
  54. DEFINE_ALGORITHMS(asym_ciphers, EVP_ASYM_CIPHER)
  55. static OSSL_LIB_CTX *libctx = NULL;
  56. int FuzzerInitialize(int *argc, char ***argv)
  57. {
  58. libctx = OSSL_LIB_CTX_new();
  59. if (libctx == NULL)
  60. return 0;
  61. init_digests(libctx);
  62. init_kdf(libctx);
  63. init_cipher(libctx);
  64. init_kem(libctx);
  65. init_keyexch(libctx);
  66. init_rand(libctx);
  67. init_mac(libctx);
  68. init_keymgmt(libctx);
  69. init_signature(libctx);
  70. init_asym_ciphers(libctx);
  71. return 1;
  72. }
  73. void FuzzerCleanup(void)
  74. {
  75. cleanup_digests();
  76. cleanup_kdf();
  77. cleanup_cipher();
  78. cleanup_kem();
  79. cleanup_keyexch();
  80. cleanup_rand();
  81. cleanup_mac();
  82. cleanup_keymgmt();
  83. cleanup_signature();
  84. cleanup_asym_ciphers();
  85. OSSL_LIB_CTX_free(libctx);
  86. }
  87. static int read_uint(const uint8_t **buf, size_t *len, uint64_t **res)
  88. {
  89. int r = 1;
  90. if (*len < sizeof(uint64_t)) {
  91. r = 0;
  92. goto end;
  93. }
  94. *res = OPENSSL_malloc(sizeof(uint64_t));
  95. **res = (uint64_t) **buf;
  96. *buf += sizeof(uint64_t);
  97. *len -= sizeof(uint64_t);
  98. end:
  99. return r;
  100. }
  101. static int read_int(const uint8_t **buf, size_t *len, int64_t **res)
  102. {
  103. int r = 1;
  104. if (*len < sizeof(int64_t)) {
  105. r = 0;
  106. goto end;
  107. }
  108. *res = OPENSSL_malloc(sizeof(int64_t));
  109. **res = (int64_t) **buf;
  110. *buf += sizeof(int64_t);
  111. *len -= sizeof(int64_t);
  112. end:
  113. return r;
  114. }
  115. static int read_double(const uint8_t **buf, size_t *len, double **res)
  116. {
  117. int r = 1;
  118. if (*len < sizeof(double)) {
  119. r = 0;
  120. goto end;
  121. }
  122. *res = OPENSSL_malloc(sizeof(double));
  123. **res = (double) **buf;
  124. *buf += sizeof(double);
  125. *len -= sizeof(double);
  126. end:
  127. return r;
  128. }
  129. static int read_utf8_string(const uint8_t **buf, size_t *len, char **res)
  130. {
  131. size_t found_len;
  132. int r;
  133. found_len = strnlen((const char *) *buf, *len);
  134. if (found_len == *len) {
  135. r = -1;
  136. goto end;
  137. }
  138. found_len++; /* skip over the \0 byte */
  139. r = (int) found_len;
  140. *res = (char *) *buf;
  141. *len -= found_len;
  142. *buf = *buf + found_len; /* continue after the \0 byte */
  143. end:
  144. return r;
  145. }
  146. static int read_utf8_ptr(const uint8_t **buf, size_t *len, char **res)
  147. {
  148. if (*len > 0 && **buf == 0xFF) {
  149. /* represent NULL somehow */
  150. *res = NULL;
  151. *buf += 1;
  152. *len -= 1;
  153. return 0;
  154. }
  155. return read_utf8_string(buf, len, res);
  156. }
  157. static int read_octet_string(const uint8_t **buf, size_t *len, char **res)
  158. {
  159. int r;
  160. size_t i;
  161. const uint8_t *ptr = *buf;
  162. int found = 0;
  163. for (i = 0; i < *len; ++i) {
  164. if (*ptr == 0xFF &&
  165. (i + 1 < *len && *(ptr + 1) == 0xFF)) {
  166. ptr++;
  167. found = 1;
  168. break;
  169. }
  170. ptr++;
  171. }
  172. if (!found) {
  173. r = -1;
  174. goto end;
  175. }
  176. *res = (char *) *buf;
  177. r = ptr - *buf;
  178. *len -= r;
  179. *buf = ptr;
  180. end:
  181. return r;
  182. }
  183. static int read_octet_ptr(const uint8_t **buf, size_t *len, char **res)
  184. {
  185. /* TODO: This representation could need an improvement potentially. */
  186. if (*len > 1 && **buf == 0xFF && *(*buf + 1) == 0xFF) {
  187. /* represent NULL somehow */
  188. *res = NULL;
  189. *buf += 2;
  190. *len -= 2;
  191. return 0;
  192. }
  193. return read_octet_string(buf, len, res);
  194. }
  195. static char *DFLT_STR = "";
  196. static char *DFLT_UTF8_PTR = NULL;
  197. static char *DFLT_OCTET_STRING = "";
  198. static char *DFLT_OCTET_PTR = NULL;
  199. static int64_t ITERS = 1;
  200. static uint64_t UITERS = 1;
  201. static int64_t BLOCKSIZE = 8;
  202. static uint64_t UBLOCKSIZE = 8;
  203. static void free_params(OSSL_PARAM *param)
  204. {
  205. for (; param != NULL && param->key != NULL; param++) {
  206. switch (param->data_type) {
  207. case OSSL_PARAM_INTEGER:
  208. case OSSL_PARAM_UNSIGNED_INTEGER:
  209. case OSSL_PARAM_REAL:
  210. if (param->data != NULL) {
  211. OPENSSL_free(param->data);
  212. }
  213. break;
  214. }
  215. }
  216. }
  217. static OSSL_PARAM *fuzz_params(OSSL_PARAM *param, const uint8_t **buf, size_t *len)
  218. {
  219. OSSL_PARAM *p;
  220. OSSL_PARAM *fuzzed_parameters;
  221. int p_num = 0;
  222. for (p = param; p != NULL && p->key != NULL; p++)
  223. p_num++;
  224. fuzzed_parameters = OPENSSL_zalloc(sizeof(OSSL_PARAM) *(p_num + 1));
  225. p = fuzzed_parameters;
  226. for (; param != NULL && param->key != NULL; param++) {
  227. int64_t *use_param = NULL;
  228. int64_t *p_value_int = NULL;
  229. uint64_t *p_value_uint = NULL;
  230. double *p_value_double = NULL;
  231. char *p_value_utf8_str = DFLT_STR;
  232. char *p_value_octet_str = DFLT_OCTET_STRING;
  233. char *p_value_utf8_ptr = DFLT_UTF8_PTR;
  234. char *p_value_octet_ptr = DFLT_OCTET_PTR;
  235. int data_len = 0;
  236. if (!read_int(buf, len, &use_param)) {
  237. use_param = OPENSSL_malloc(sizeof(uint64_t));
  238. *use_param = 0;
  239. }
  240. switch (param->data_type) {
  241. case OSSL_PARAM_INTEGER:
  242. if (strcmp(param->key, OSSL_KDF_PARAM_ITER) == 0) {
  243. p_value_int = OPENSSL_malloc(sizeof(ITERS));
  244. *p_value_int = ITERS;
  245. } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_N) == 0) {
  246. p_value_int = OPENSSL_malloc(sizeof(ITERS));
  247. *p_value_int = ITERS;
  248. } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_R) == 0) {
  249. p_value_int = OPENSSL_malloc(sizeof(BLOCKSIZE));
  250. *p_value_int = BLOCKSIZE;
  251. } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_P) == 0) {
  252. p_value_int = OPENSSL_malloc(sizeof(BLOCKSIZE));
  253. *p_value_int = BLOCKSIZE;
  254. } else if (!*use_param || !read_int(buf, len, &p_value_int)) {
  255. p_value_int = OPENSSL_malloc(sizeof(int64_t));
  256. *p_value_int = 0;
  257. }
  258. *p = *param;
  259. p->data = p_value_int;
  260. p++;
  261. break;
  262. case OSSL_PARAM_UNSIGNED_INTEGER:
  263. if (strcmp(param->key, OSSL_KDF_PARAM_ITER) == 0) {
  264. p_value_uint = OPENSSL_malloc(sizeof(UITERS));
  265. *p_value_uint = UITERS;
  266. } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_N) == 0) {
  267. p_value_uint = OPENSSL_malloc(sizeof(UITERS));
  268. *p_value_uint = UITERS;
  269. } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_R) == 0) {
  270. p_value_uint = OPENSSL_malloc(sizeof(UBLOCKSIZE));
  271. *p_value_uint = UBLOCKSIZE;
  272. } else if (strcmp(param->key, OSSL_KDF_PARAM_SCRYPT_P) == 0) {
  273. p_value_uint = OPENSSL_malloc(sizeof(UBLOCKSIZE));
  274. *p_value_uint = UBLOCKSIZE;
  275. } else if (!*use_param || !read_uint(buf, len, &p_value_uint)) {
  276. p_value_uint = OPENSSL_malloc(sizeof(uint64_t));
  277. *p_value_uint = 0;
  278. }
  279. *p = *param;
  280. p->data = p_value_uint;
  281. p++;
  282. break;
  283. case OSSL_PARAM_REAL:
  284. if (!*use_param || !read_double(buf, len, &p_value_double)) {
  285. p_value_double = OPENSSL_malloc(sizeof(double));
  286. *p_value_double = 0;
  287. }
  288. *p = *param;
  289. p->data = p_value_double;
  290. p++;
  291. break;
  292. case OSSL_PARAM_UTF8_STRING:
  293. if (*use_param && (data_len = read_utf8_string(buf, len, &p_value_utf8_str)) < 0)
  294. data_len = 0;
  295. *p = *param;
  296. p->data = p_value_utf8_str;
  297. p->data_size = data_len;
  298. p++;
  299. break;
  300. case OSSL_PARAM_OCTET_STRING:
  301. if (*use_param && (data_len = read_octet_string(buf, len, &p_value_octet_str)) < 0)
  302. data_len = 0;
  303. *p = *param;
  304. p->data = p_value_octet_str;
  305. p->data_size = data_len;
  306. p++;
  307. break;
  308. case OSSL_PARAM_UTF8_PTR:
  309. if (*use_param && (data_len = read_utf8_ptr(buf, len, &p_value_utf8_ptr)) < 0)
  310. data_len = 0;
  311. *p = *param;
  312. p->data = p_value_utf8_ptr;
  313. p->data_size = data_len;
  314. p++;
  315. break;
  316. case OSSL_PARAM_OCTET_PTR:
  317. if (*use_param && (data_len = read_octet_ptr(buf, len, &p_value_octet_ptr)) < 0)
  318. data_len = 0;
  319. *p = *param;
  320. p->data = p_value_octet_ptr;
  321. p->data_size = data_len;
  322. p++;
  323. break;
  324. default:
  325. break;
  326. }
  327. OPENSSL_free(use_param);
  328. }
  329. return fuzzed_parameters;
  330. }
  331. static int do_evp_cipher(const EVP_CIPHER *evp_cipher, const OSSL_PARAM param[])
  332. {
  333. unsigned char outbuf[1024];
  334. int outlen, tmplen;
  335. unsigned char key[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  336. unsigned char iv[] = {1, 2, 3, 4, 5, 6, 7, 8};
  337. const char intext[] = "text";
  338. EVP_CIPHER_CTX *ctx;
  339. ctx = EVP_CIPHER_CTX_new();
  340. if (!EVP_CIPHER_CTX_set_params(ctx, param)) {
  341. EVP_CIPHER_CTX_free(ctx);
  342. return 0;
  343. }
  344. if (!EVP_EncryptInit_ex2(ctx, evp_cipher, key, iv, NULL)) {
  345. /* Error */
  346. EVP_CIPHER_CTX_free(ctx);
  347. return 0;
  348. }
  349. if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, (const unsigned char *) intext, strlen(intext))) {
  350. /* Error */
  351. EVP_CIPHER_CTX_free(ctx);
  352. return 0;
  353. }
  354. /*
  355. * Buffer passed to EVP_EncryptFinal() must be after data just
  356. * encrypted to avoid overwriting it.
  357. */
  358. if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) {
  359. /* Error */
  360. EVP_CIPHER_CTX_free(ctx);
  361. return 0;
  362. }
  363. outlen += tmplen;
  364. EVP_CIPHER_CTX_free(ctx);
  365. return 1;
  366. }
  367. static int do_evp_kdf(EVP_KDF *evp_kdf, const OSSL_PARAM params[])
  368. {
  369. int r = 1;
  370. EVP_KDF_CTX *kctx = NULL;
  371. unsigned char derived[32];
  372. kctx = EVP_KDF_CTX_new(evp_kdf);
  373. if (kctx == NULL) {
  374. r = 0;
  375. goto end;
  376. }
  377. if (EVP_KDF_CTX_set_params(kctx, params) <= 0) {
  378. r = 0;
  379. goto end;
  380. }
  381. if (EVP_KDF_derive(kctx, derived, sizeof(derived), NULL) <= 0) {
  382. r = 0;
  383. goto end;
  384. }
  385. end:
  386. EVP_KDF_CTX_free(kctx);
  387. return r;
  388. }
  389. static int do_evp_mac(EVP_MAC *evp_mac, const OSSL_PARAM params[])
  390. {
  391. int r = 1;
  392. const char *key = "mac_key";
  393. char text[] = "Some Crypto Text";
  394. EVP_MAC_CTX *ctx = NULL;
  395. unsigned char buf[4096];
  396. size_t final_l;
  397. if ((ctx = EVP_MAC_CTX_new(evp_mac)) == NULL
  398. || !EVP_MAC_init(ctx, (const unsigned char *) key, strlen(key),
  399. params)) {
  400. r = 0;
  401. goto end;
  402. }
  403. if (EVP_MAC_CTX_set_params(ctx, params) <= 0) {
  404. r = 0;
  405. goto end;
  406. }
  407. if (!EVP_MAC_update(ctx, (unsigned char *) text, sizeof(text))) {
  408. r = 0;
  409. goto end;
  410. }
  411. if (!EVP_MAC_final(ctx, buf, &final_l, sizeof(buf))) {
  412. r = 0;
  413. goto end;
  414. }
  415. end:
  416. EVP_MAC_CTX_free(ctx);
  417. return r;
  418. }
  419. static int do_evp_rand(EVP_RAND *evp_rand, const OSSL_PARAM params[])
  420. {
  421. int r = 1;
  422. EVP_RAND_CTX *ctx = NULL;
  423. unsigned char buf[4096];
  424. if (!(ctx = EVP_RAND_CTX_new(evp_rand, NULL))) {
  425. r = 0;
  426. goto end;
  427. }
  428. if (EVP_RAND_CTX_set_params(ctx, params) <= 0) {
  429. r = 0;
  430. goto end;
  431. }
  432. if (!EVP_RAND_generate(ctx, buf, sizeof(buf), 0, 0, NULL, 0)) {
  433. r = 0;
  434. goto end;
  435. }
  436. if (!EVP_RAND_reseed(ctx, 0, 0, 0, NULL, 0)) {
  437. r = 0;
  438. goto end;
  439. }
  440. end:
  441. EVP_RAND_CTX_free(ctx);
  442. return r;
  443. }
  444. static int do_evp_sig(EVP_SIGNATURE *evp_sig, const OSSL_PARAM params[])
  445. {
  446. return 0;
  447. }
  448. static int do_evp_asym_cipher(EVP_ASYM_CIPHER *evp_asym_cipher, const OSSL_PARAM params[])
  449. {
  450. return 0;
  451. }
  452. static int do_evp_kem(EVP_KEM *evp_kem, const OSSL_PARAM params[])
  453. {
  454. return 0;
  455. }
  456. static int do_evp_key_exch(EVP_KEYEXCH *evp_kdf, const OSSL_PARAM params[])
  457. {
  458. return 0;
  459. }
  460. static int do_evp_md(EVP_MD *evp_md, const OSSL_PARAM params[])
  461. {
  462. int r = 1;
  463. unsigned char md_value[EVP_MAX_MD_SIZE];
  464. unsigned int md_len;
  465. EVP_MD_CTX *mdctx = NULL;
  466. if (!(mdctx = EVP_MD_CTX_new())) {
  467. r = 0;
  468. goto end;
  469. }
  470. if (!EVP_MD_CTX_set_params(mdctx, params)) {
  471. r = 0;
  472. goto end;
  473. }
  474. if (!EVP_DigestInit_ex2(mdctx, evp_md, NULL)) {
  475. r = 0;
  476. goto end;
  477. }
  478. if (!EVP_DigestUpdate(mdctx, "Test", strlen("Test"))) {
  479. r = 0;
  480. goto end;
  481. }
  482. if (!EVP_DigestFinal_ex(mdctx, md_value, &md_len)) {
  483. r = 0;
  484. goto end;
  485. }
  486. end:
  487. EVP_MD_CTX_free(mdctx);
  488. return r;
  489. }
  490. #define EVP_FUZZ(source, evp, f) \
  491. do { \
  492. evp *alg = sk_##evp##_value(source, *algorithm % sk_##evp##_num(source)); \
  493. OSSL_PARAM *fuzzed_params; \
  494. \
  495. if (alg == NULL) \
  496. break; \
  497. fuzzed_params = fuzz_params((OSSL_PARAM*) evp##_settable_ctx_params(alg), &buf, &len); \
  498. if (fuzzed_params != NULL) \
  499. f(alg, fuzzed_params); \
  500. free_params(fuzzed_params); \
  501. OSSL_PARAM_free(fuzzed_params); \
  502. } while (0);
  503. int FuzzerTestOneInput(const uint8_t *buf, size_t len)
  504. {
  505. int r = 1;
  506. uint64_t *operation = NULL;
  507. int64_t *algorithm = NULL;
  508. if (!read_uint(&buf, &len, &operation)) {
  509. r = 0;
  510. goto end;
  511. }
  512. if (!read_int(&buf, &len, &algorithm)) {
  513. r = 0;
  514. goto end;
  515. }
  516. switch (*operation % 10) {
  517. case 0:
  518. EVP_FUZZ(digests_collection, EVP_MD, do_evp_md);
  519. break;
  520. case 1:
  521. EVP_FUZZ(cipher_collection, EVP_CIPHER, do_evp_cipher);
  522. break;
  523. case 2:
  524. EVP_FUZZ(kdf_collection, EVP_KDF, do_evp_kdf);
  525. break;
  526. case 3:
  527. EVP_FUZZ(mac_collection, EVP_MAC, do_evp_mac);
  528. break;
  529. case 4:
  530. EVP_FUZZ(kem_collection, EVP_KEM, do_evp_kem);
  531. break;
  532. case 5:
  533. EVP_FUZZ(rand_collection, EVP_RAND, do_evp_rand);
  534. break;
  535. case 6:
  536. EVP_FUZZ(asym_ciphers_collection, EVP_ASYM_CIPHER, do_evp_asym_cipher);
  537. break;
  538. case 7:
  539. EVP_FUZZ(signature_collection, EVP_SIGNATURE, do_evp_sig);
  540. break;
  541. case 8:
  542. EVP_FUZZ(keyexch_collection, EVP_KEYEXCH, do_evp_key_exch);
  543. break;
  544. case 9:
  545. /*
  546. Implement and call:
  547. static int do_evp_keymgmt(EVP_KEYMGMT *evp_kdf, const OSSL_PARAM params[])
  548. {
  549. return 0;
  550. }
  551. */
  552. /* not yet implemented */
  553. break;
  554. default:
  555. r = 0;
  556. goto end;
  557. }
  558. end:
  559. OPENSSL_free(operation);
  560. OPENSSL_free(algorithm);
  561. return r;
  562. }