eng_openssl.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /* crypto/engine/eng_openssl.c */
  2. /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
  3. * project 2000.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * licensing@OpenSSL.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. *
  53. * This product includes cryptographic software written by Eric Young
  54. * (eay@cryptsoft.com). This product includes software written by Tim
  55. * Hudson (tjh@cryptsoft.com).
  56. *
  57. */
  58. /* ====================================================================
  59. * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  60. * ECDH support in OpenSSL originally developed by
  61. * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  62. */
  63. #include <stdio.h>
  64. #include <openssl/crypto.h>
  65. #include "cryptlib.h"
  66. #include <openssl/engine.h>
  67. #include <openssl/dso.h>
  68. #include <openssl/pem.h>
  69. #include <openssl/evp.h>
  70. #include <openssl/rand.h>
  71. #ifndef OPENSSL_NO_RSA
  72. #include <openssl/rsa.h>
  73. #endif
  74. #ifndef OPENSSL_NO_DSA
  75. #include <openssl/dsa.h>
  76. #endif
  77. #ifndef OPENSSL_NO_DH
  78. #include <openssl/dh.h>
  79. #endif
  80. #include <openssl/hmac.h>
  81. #include <openssl/x509v3.h>
  82. /* This testing gunk is implemented (and explained) lower down. It also assumes
  83. * the application explicitly calls "ENGINE_load_openssl()" because this is no
  84. * longer automatic in ENGINE_load_builtin_engines(). */
  85. #define TEST_ENG_OPENSSL_RC4
  86. #define TEST_ENG_OPENSSL_PKEY
  87. /* #define TEST_ENG_OPENSSL_HMAC */
  88. /* #define TEST_ENG_OPENSSL_HMAC_INIT */
  89. /* #define TEST_ENG_OPENSSL_RC4_OTHERS */
  90. #define TEST_ENG_OPENSSL_RC4_P_INIT
  91. /* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
  92. #define TEST_ENG_OPENSSL_SHA
  93. /* #define TEST_ENG_OPENSSL_SHA_OTHERS */
  94. /* #define TEST_ENG_OPENSSL_SHA_P_INIT */
  95. /* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
  96. /* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
  97. /* Now check what of those algorithms are actually enabled */
  98. #ifdef OPENSSL_NO_RC4
  99. #undef TEST_ENG_OPENSSL_RC4
  100. #undef TEST_ENG_OPENSSL_RC4_OTHERS
  101. #undef TEST_ENG_OPENSSL_RC4_P_INIT
  102. #undef TEST_ENG_OPENSSL_RC4_P_CIPHER
  103. #endif
  104. #if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1)
  105. #undef TEST_ENG_OPENSSL_SHA
  106. #undef TEST_ENG_OPENSSL_SHA_OTHERS
  107. #undef TEST_ENG_OPENSSL_SHA_P_INIT
  108. #undef TEST_ENG_OPENSSL_SHA_P_UPDATE
  109. #undef TEST_ENG_OPENSSL_SHA_P_FINAL
  110. #endif
  111. #ifdef TEST_ENG_OPENSSL_RC4
  112. static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
  113. const int **nids, int nid);
  114. #endif
  115. #ifdef TEST_ENG_OPENSSL_SHA
  116. static int openssl_digests(ENGINE *e, const EVP_MD **digest,
  117. const int **nids, int nid);
  118. #endif
  119. #ifdef TEST_ENG_OPENSSL_PKEY
  120. static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
  121. UI_METHOD *ui_method, void *callback_data);
  122. #endif
  123. #ifdef TEST_ENG_OPENSSL_HMAC
  124. static int ossl_register_hmac_meth(void);
  125. static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
  126. const int **nids, int nid);
  127. #endif
  128. /* The constants used when creating the ENGINE */
  129. static const char *engine_openssl_id = "openssl";
  130. static const char *engine_openssl_name = "Software engine support";
  131. /* This internal function is used by ENGINE_openssl() and possibly by the
  132. * "dynamic" ENGINE support too */
  133. static int bind_helper(ENGINE *e)
  134. {
  135. if(!ENGINE_set_id(e, engine_openssl_id)
  136. || !ENGINE_set_name(e, engine_openssl_name)
  137. #ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
  138. #ifndef OPENSSL_NO_RSA
  139. || !ENGINE_set_RSA(e, RSA_get_default_method())
  140. #endif
  141. #ifndef OPENSSL_NO_DSA
  142. || !ENGINE_set_DSA(e, DSA_get_default_method())
  143. #endif
  144. #ifndef OPENSSL_NO_ECDH
  145. || !ENGINE_set_ECDH(e, ECDH_OpenSSL())
  146. #endif
  147. #ifndef OPENSSL_NO_ECDSA
  148. || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
  149. #endif
  150. #ifndef OPENSSL_NO_DH
  151. || !ENGINE_set_DH(e, DH_get_default_method())
  152. #endif
  153. || !ENGINE_set_RAND(e, RAND_SSLeay())
  154. #ifdef TEST_ENG_OPENSSL_RC4
  155. || !ENGINE_set_ciphers(e, openssl_ciphers)
  156. #endif
  157. #ifdef TEST_ENG_OPENSSL_SHA
  158. || !ENGINE_set_digests(e, openssl_digests)
  159. #endif
  160. #endif
  161. #ifdef TEST_ENG_OPENSSL_PKEY
  162. || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
  163. #endif
  164. #ifdef TEST_ENG_OPENSSL_HMAC
  165. || !ossl_register_hmac_meth()
  166. || !ENGINE_set_pkey_meths(e, ossl_pkey_meths)
  167. #endif
  168. )
  169. return 0;
  170. /* If we add errors to this ENGINE, ensure the error handling is setup here */
  171. /* openssl_load_error_strings(); */
  172. return 1;
  173. }
  174. static ENGINE *engine_openssl(void)
  175. {
  176. ENGINE *ret = ENGINE_new();
  177. if(!ret)
  178. return NULL;
  179. if(!bind_helper(ret))
  180. {
  181. ENGINE_free(ret);
  182. return NULL;
  183. }
  184. return ret;
  185. }
  186. void ENGINE_load_openssl(void)
  187. {
  188. ENGINE *toadd = engine_openssl();
  189. if(!toadd) return;
  190. ENGINE_add(toadd);
  191. /* If the "add" worked, it gets a structural reference. So either way,
  192. * we release our just-created reference. */
  193. ENGINE_free(toadd);
  194. ERR_clear_error();
  195. }
  196. /* This stuff is needed if this ENGINE is being compiled into a self-contained
  197. * shared-library. */
  198. #ifdef ENGINE_DYNAMIC_SUPPORT
  199. static int bind_fn(ENGINE *e, const char *id)
  200. {
  201. if(id && (strcmp(id, engine_openssl_id) != 0))
  202. return 0;
  203. if(!bind_helper(e))
  204. return 0;
  205. return 1;
  206. }
  207. IMPLEMENT_DYNAMIC_CHECK_FN()
  208. IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
  209. #endif /* ENGINE_DYNAMIC_SUPPORT */
  210. #ifdef TEST_ENG_OPENSSL_RC4
  211. /* This section of code compiles an "alternative implementation" of two modes of
  212. * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
  213. * should under normal circumstances go via this support rather than the default
  214. * EVP support. There are other symbols to tweak the testing;
  215. * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
  216. * we're asked for a cipher we don't support (should not happen).
  217. * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
  218. * the "init_key" handler is called.
  219. * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
  220. */
  221. #include <openssl/rc4.h>
  222. #define TEST_RC4_KEY_SIZE 16
  223. static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
  224. static int test_cipher_nids_number = 2;
  225. typedef struct {
  226. unsigned char key[TEST_RC4_KEY_SIZE];
  227. RC4_KEY ks;
  228. } TEST_RC4_KEY;
  229. #define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
  230. static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
  231. const unsigned char *iv, int enc)
  232. {
  233. #ifdef TEST_ENG_OPENSSL_RC4_P_INIT
  234. fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
  235. #endif
  236. memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx));
  237. RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
  238. test(ctx)->key);
  239. return 1;
  240. }
  241. static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
  242. const unsigned char *in, size_t inl)
  243. {
  244. #ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
  245. fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
  246. #endif
  247. RC4(&test(ctx)->ks,inl,in,out);
  248. return 1;
  249. }
  250. static const EVP_CIPHER test_r4_cipher=
  251. {
  252. NID_rc4,
  253. 1,TEST_RC4_KEY_SIZE,0,
  254. EVP_CIPH_VARIABLE_LENGTH,
  255. test_rc4_init_key,
  256. test_rc4_cipher,
  257. NULL,
  258. sizeof(TEST_RC4_KEY),
  259. NULL,
  260. NULL,
  261. NULL,
  262. NULL
  263. };
  264. static const EVP_CIPHER test_r4_40_cipher=
  265. {
  266. NID_rc4_40,
  267. 1,5 /* 40 bit */,0,
  268. EVP_CIPH_VARIABLE_LENGTH,
  269. test_rc4_init_key,
  270. test_rc4_cipher,
  271. NULL,
  272. sizeof(TEST_RC4_KEY),
  273. NULL,
  274. NULL,
  275. NULL,
  276. NULL
  277. };
  278. static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
  279. const int **nids, int nid)
  280. {
  281. if(!cipher)
  282. {
  283. /* We are returning a list of supported nids */
  284. *nids = test_cipher_nids;
  285. return test_cipher_nids_number;
  286. }
  287. /* We are being asked for a specific cipher */
  288. if(nid == NID_rc4)
  289. *cipher = &test_r4_cipher;
  290. else if(nid == NID_rc4_40)
  291. *cipher = &test_r4_40_cipher;
  292. else
  293. {
  294. #ifdef TEST_ENG_OPENSSL_RC4_OTHERS
  295. fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
  296. "nid %d\n", nid);
  297. #endif
  298. *cipher = NULL;
  299. return 0;
  300. }
  301. return 1;
  302. }
  303. #endif
  304. #ifdef TEST_ENG_OPENSSL_SHA
  305. /* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
  306. #include <openssl/sha.h>
  307. static int test_digest_nids[] = {NID_sha1};
  308. static int test_digest_nids_number = 1;
  309. static int test_sha1_init(EVP_MD_CTX *ctx)
  310. {
  311. #ifdef TEST_ENG_OPENSSL_SHA_P_INIT
  312. fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
  313. #endif
  314. return SHA1_Init(ctx->md_data);
  315. }
  316. static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,size_t count)
  317. {
  318. #ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
  319. fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
  320. #endif
  321. return SHA1_Update(ctx->md_data,data,count);
  322. }
  323. static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md)
  324. {
  325. #ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
  326. fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
  327. #endif
  328. return SHA1_Final(md,ctx->md_data);
  329. }
  330. static const EVP_MD test_sha_md=
  331. {
  332. NID_sha1,
  333. NID_sha1WithRSAEncryption,
  334. SHA_DIGEST_LENGTH,
  335. 0,
  336. test_sha1_init,
  337. test_sha1_update,
  338. test_sha1_final,
  339. NULL,
  340. NULL,
  341. EVP_PKEY_RSA_method,
  342. SHA_CBLOCK,
  343. sizeof(EVP_MD *)+sizeof(SHA_CTX),
  344. };
  345. static int openssl_digests(ENGINE *e, const EVP_MD **digest,
  346. const int **nids, int nid)
  347. {
  348. if(!digest)
  349. {
  350. /* We are returning a list of supported nids */
  351. *nids = test_digest_nids;
  352. return test_digest_nids_number;
  353. }
  354. /* We are being asked for a specific digest */
  355. if(nid == NID_sha1)
  356. *digest = &test_sha_md;
  357. else
  358. {
  359. #ifdef TEST_ENG_OPENSSL_SHA_OTHERS
  360. fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
  361. "nid %d\n", nid);
  362. #endif
  363. *digest = NULL;
  364. return 0;
  365. }
  366. return 1;
  367. }
  368. #endif
  369. #ifdef TEST_ENG_OPENSSL_PKEY
  370. static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
  371. UI_METHOD *ui_method, void *callback_data)
  372. {
  373. BIO *in;
  374. EVP_PKEY *key;
  375. fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
  376. in = BIO_new_file(key_id, "r");
  377. if (!in)
  378. return NULL;
  379. key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
  380. BIO_free(in);
  381. return key;
  382. }
  383. #endif
  384. #ifdef TEST_ENG_OPENSSL_HMAC
  385. /* Experimental HMAC redirection implementation: mainly copied from
  386. * hm_pmeth.c
  387. */
  388. /* HMAC pkey context structure */
  389. typedef struct
  390. {
  391. const EVP_MD *md; /* MD for HMAC use */
  392. ASN1_OCTET_STRING ktmp; /* Temp storage for key */
  393. HMAC_CTX ctx;
  394. } OSSL_HMAC_PKEY_CTX;
  395. static int ossl_hmac_init(EVP_PKEY_CTX *ctx)
  396. {
  397. OSSL_HMAC_PKEY_CTX *hctx;
  398. hctx = OPENSSL_malloc(sizeof(OSSL_HMAC_PKEY_CTX));
  399. if (!hctx)
  400. return 0;
  401. hctx->md = NULL;
  402. hctx->ktmp.data = NULL;
  403. hctx->ktmp.length = 0;
  404. hctx->ktmp.flags = 0;
  405. hctx->ktmp.type = V_ASN1_OCTET_STRING;
  406. HMAC_CTX_init(&hctx->ctx);
  407. EVP_PKEY_CTX_set_data(ctx, hctx);
  408. EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0);
  409. #ifdef TEST_ENG_OPENSSL_HMAC_INIT
  410. fprintf(stderr, "(TEST_ENG_OPENSSL_HMAC) ossl_hmac_init() called\n");
  411. #endif
  412. return 1;
  413. }
  414. static int ossl_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
  415. {
  416. OSSL_HMAC_PKEY_CTX *sctx, *dctx;
  417. if (!ossl_hmac_init(dst))
  418. return 0;
  419. sctx = EVP_PKEY_CTX_get_data(src);
  420. dctx = EVP_PKEY_CTX_get_data(dst);
  421. dctx->md = sctx->md;
  422. HMAC_CTX_init(&dctx->ctx);
  423. if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
  424. return 0;
  425. if (sctx->ktmp.data)
  426. {
  427. if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
  428. sctx->ktmp.data, sctx->ktmp.length))
  429. return 0;
  430. }
  431. return 1;
  432. }
  433. static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx)
  434. {
  435. OSSL_HMAC_PKEY_CTX *hctx;
  436. hctx = EVP_PKEY_CTX_get_data(ctx);
  437. HMAC_CTX_cleanup(&hctx->ctx);
  438. if (hctx->ktmp.data)
  439. {
  440. if (hctx->ktmp.length)
  441. OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length);
  442. OPENSSL_free(hctx->ktmp.data);
  443. hctx->ktmp.data = NULL;
  444. }
  445. OPENSSL_free(hctx);
  446. }
  447. static int ossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
  448. {
  449. ASN1_OCTET_STRING *hkey = NULL;
  450. OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
  451. if (!hctx->ktmp.data)
  452. return 0;
  453. hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
  454. if (!hkey)
  455. return 0;
  456. EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
  457. return 1;
  458. }
  459. static int ossl_int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
  460. {
  461. OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx->pctx);
  462. if (!HMAC_Update(&hctx->ctx, data, count))
  463. return 0;
  464. return 1;
  465. }
  466. static int ossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
  467. {
  468. EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
  469. mctx->update = ossl_int_update;
  470. return 1;
  471. }
  472. static int ossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
  473. EVP_MD_CTX *mctx)
  474. {
  475. unsigned int hlen;
  476. OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
  477. int l = EVP_MD_CTX_size(mctx);
  478. if (l < 0)
  479. return 0;
  480. *siglen = l;
  481. if (!sig)
  482. return 1;
  483. if (!HMAC_Final(&hctx->ctx, sig, &hlen))
  484. return 0;
  485. *siglen = (size_t)hlen;
  486. return 1;
  487. }
  488. static int ossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
  489. {
  490. OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
  491. EVP_PKEY *pk;
  492. ASN1_OCTET_STRING *key;
  493. switch (type)
  494. {
  495. case EVP_PKEY_CTRL_SET_MAC_KEY:
  496. if ((!p2 && p1 > 0) || (p1 < -1))
  497. return 0;
  498. if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
  499. return 0;
  500. break;
  501. case EVP_PKEY_CTRL_MD:
  502. hctx->md = p2;
  503. break;
  504. case EVP_PKEY_CTRL_DIGESTINIT:
  505. pk = EVP_PKEY_CTX_get0_pkey(ctx);
  506. key = EVP_PKEY_get0(pk);
  507. if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
  508. NULL))
  509. return 0;
  510. break;
  511. default:
  512. return -2;
  513. }
  514. return 1;
  515. }
  516. static int ossl_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
  517. const char *type, const char *value)
  518. {
  519. if (!value)
  520. {
  521. return 0;
  522. }
  523. if (!strcmp(type, "key"))
  524. {
  525. void *p = (void *)value;
  526. return ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
  527. -1, p);
  528. }
  529. if (!strcmp(type, "hexkey"))
  530. {
  531. unsigned char *key;
  532. int r;
  533. long keylen;
  534. key = string_to_hex(value, &keylen);
  535. if (!key)
  536. return 0;
  537. r = ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
  538. OPENSSL_free(key);
  539. return r;
  540. }
  541. return -2;
  542. }
  543. static EVP_PKEY_METHOD *ossl_hmac_meth;
  544. static int ossl_register_hmac_meth(void)
  545. {
  546. EVP_PKEY_METHOD *meth;
  547. meth = EVP_PKEY_meth_new(EVP_PKEY_HMAC, 0);
  548. if (!meth)
  549. return 0;
  550. EVP_PKEY_meth_set_init(meth, ossl_hmac_init);
  551. EVP_PKEY_meth_set_copy(meth, ossl_hmac_copy);
  552. EVP_PKEY_meth_set_cleanup(meth, ossl_hmac_cleanup);
  553. EVP_PKEY_meth_set_keygen(meth, 0, ossl_hmac_keygen);
  554. EVP_PKEY_meth_set_signctx(meth, ossl_hmac_signctx_init,
  555. ossl_hmac_signctx);
  556. EVP_PKEY_meth_set_ctrl(meth, ossl_hmac_ctrl, ossl_hmac_ctrl_str);
  557. ossl_hmac_meth = meth;
  558. return 1;
  559. }
  560. static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
  561. const int **nids, int nid)
  562. {
  563. static int ossl_pkey_nids[] =
  564. {
  565. EVP_PKEY_HMAC,
  566. 0
  567. };
  568. if (!pmeth)
  569. {
  570. *nids = ossl_pkey_nids;
  571. return 1;
  572. }
  573. if (nid == EVP_PKEY_HMAC)
  574. {
  575. *pmeth = ossl_hmac_meth;
  576. return 1;
  577. }
  578. *pmeth = NULL;
  579. return 0;
  580. }
  581. #endif