e_4758cca.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. /* Author: Maurice Gittens <maurice@gittens.nl> */
  2. /* ====================================================================
  3. * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in
  14. * the documentation and/or other materials provided with the
  15. * distribution.
  16. *
  17. * 3. All advertising materials mentioning features or use of this
  18. * software must display the following acknowledgment:
  19. * "This product includes software developed by the OpenSSL Project
  20. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  21. *
  22. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  23. * endorse or promote products derived from this software without
  24. * prior written permission. For written permission, please contact
  25. * licensing@OpenSSL.org.
  26. *
  27. * 5. Products derived from this software may not be called "OpenSSL"
  28. * nor may "OpenSSL" appear in their names without prior written
  29. * permission of the OpenSSL Project.
  30. *
  31. * 6. Redistributions of any form whatsoever must retain the following
  32. * acknowledgment:
  33. * "This product includes software developed by the OpenSSL Project
  34. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  35. *
  36. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  37. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  38. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  39. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  42. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  44. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  45. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  46. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  47. * OF THE POSSIBILITY OF SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This product includes cryptographic software written by Eric Young
  51. * (eay@cryptsoft.com). This product includes software written by Tim
  52. * Hudson (tjh@cryptsoft.com).
  53. *
  54. */
  55. #include <stdio.h>
  56. #include <string.h>
  57. #include <openssl/crypto.h>
  58. #include <openssl/dso.h>
  59. #include <openssl/x509.h>
  60. #include <openssl/objects.h>
  61. #include <openssl/engine.h>
  62. #include <openssl/rand.h>
  63. #ifndef OPENSSL_NO_RSA
  64. # include <openssl/rsa.h>
  65. #endif
  66. #include <openssl/bn.h>
  67. #ifndef OPENSSL_NO_HW
  68. # ifndef OPENSSL_NO_HW_4758_CCA
  69. # ifdef FLAT_INC
  70. # include "hw_4758_cca.h"
  71. # else
  72. # include "vendor_defns/hw_4758_cca.h"
  73. # endif
  74. # include "e_4758cca_err.c"
  75. static int ibm_4758_cca_destroy(ENGINE *e);
  76. static int ibm_4758_cca_init(ENGINE *e);
  77. static int ibm_4758_cca_finish(ENGINE *e);
  78. static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p,
  79. void (*f) (void));
  80. /* rsa functions */
  81. /* -------------*/
  82. # ifndef OPENSSL_NO_RSA
  83. static int cca_rsa_pub_enc(int flen, const unsigned char *from,
  84. unsigned char *to, RSA *rsa, int padding);
  85. static int cca_rsa_priv_dec(int flen, const unsigned char *from,
  86. unsigned char *to, RSA *rsa, int padding);
  87. static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
  88. unsigned char *sigret, unsigned int *siglen,
  89. const RSA *rsa);
  90. static int cca_rsa_verify(int dtype, const unsigned char *m,
  91. unsigned int m_len, const unsigned char *sigbuf,
  92. unsigned int siglen, const RSA *rsa);
  93. /* utility functions */
  94. /* ---------------------*/
  95. static EVP_PKEY *ibm_4758_load_privkey(ENGINE *, const char *,
  96. UI_METHOD *ui_method,
  97. void *callback_data);
  98. static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *, const char *,
  99. UI_METHOD *ui_method,
  100. void *callback_data);
  101. static int getModulusAndExponent(const unsigned char *token,
  102. long *exponentLength,
  103. unsigned char *exponent, long *modulusLength,
  104. long *modulusFieldLength,
  105. unsigned char *modulus);
  106. # endif
  107. /* RAND number functions */
  108. /* ---------------------*/
  109. static int cca_get_random_bytes(unsigned char *, int);
  110. static int cca_random_status(void);
  111. # ifndef OPENSSL_NO_RSA
  112. static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
  113. int idx, long argl, void *argp);
  114. # endif
  115. /* Function pointers for CCA verbs */
  116. /* -------------------------------*/
  117. # ifndef OPENSSL_NO_RSA
  118. static F_KEYRECORDREAD keyRecordRead;
  119. static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
  120. static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
  121. static F_PUBLICKEYEXTRACT publicKeyExtract;
  122. static F_PKAENCRYPT pkaEncrypt;
  123. static F_PKADECRYPT pkaDecrypt;
  124. # endif
  125. static F_RANDOMNUMBERGENERATE randomNumberGenerate;
  126. /* static variables */
  127. /* ----------------*/
  128. static const char *CCA4758_LIB_NAME = NULL;
  129. static const char *get_CCA4758_LIB_NAME(void)
  130. {
  131. if (CCA4758_LIB_NAME)
  132. return CCA4758_LIB_NAME;
  133. return CCA_LIB_NAME;
  134. }
  135. static void free_CCA4758_LIB_NAME(void)
  136. {
  137. if (CCA4758_LIB_NAME)
  138. OPENSSL_free((void *)CCA4758_LIB_NAME);
  139. CCA4758_LIB_NAME = NULL;
  140. }
  141. static long set_CCA4758_LIB_NAME(const char *name)
  142. {
  143. free_CCA4758_LIB_NAME();
  144. return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0);
  145. }
  146. # ifndef OPENSSL_NO_RSA
  147. static const char *n_keyRecordRead = CSNDKRR;
  148. static const char *n_digitalSignatureGenerate = CSNDDSG;
  149. static const char *n_digitalSignatureVerify = CSNDDSV;
  150. static const char *n_publicKeyExtract = CSNDPKX;
  151. static const char *n_pkaEncrypt = CSNDPKE;
  152. static const char *n_pkaDecrypt = CSNDPKD;
  153. # endif
  154. static const char *n_randomNumberGenerate = CSNBRNG;
  155. # ifndef OPENSSL_NO_RSA
  156. static int hndidx = -1;
  157. # endif
  158. static DSO *dso = NULL;
  159. /* openssl engine initialization structures */
  160. /* ----------------------------------------*/
  161. # define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
  162. static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
  163. {CCA4758_CMD_SO_PATH,
  164. "SO_PATH",
  165. "Specifies the path to the '4758cca' shared library",
  166. ENGINE_CMD_FLAG_STRING},
  167. {0, NULL, NULL, 0}
  168. };
  169. # ifndef OPENSSL_NO_RSA
  170. static RSA_METHOD ibm_4758_cca_rsa = {
  171. "IBM 4758 CCA RSA method",
  172. cca_rsa_pub_enc,
  173. NULL,
  174. NULL,
  175. cca_rsa_priv_dec,
  176. NULL, /* rsa_mod_exp, */
  177. NULL, /* mod_exp_mont, */
  178. NULL, /* init */
  179. NULL, /* finish */
  180. RSA_FLAG_SIGN_VER, /* flags */
  181. NULL, /* app_data */
  182. cca_rsa_sign, /* rsa_sign */
  183. cca_rsa_verify, /* rsa_verify */
  184. NULL /* rsa_keygen */
  185. };
  186. # endif
  187. static RAND_METHOD ibm_4758_cca_rand = {
  188. /* "IBM 4758 RAND method", */
  189. NULL, /* seed */
  190. cca_get_random_bytes, /* get random bytes from the card */
  191. NULL, /* cleanup */
  192. NULL, /* add */
  193. cca_get_random_bytes, /* pseudo rand */
  194. cca_random_status, /* status */
  195. };
  196. static const char *engine_4758_cca_id = "4758cca";
  197. static const char *engine_4758_cca_name =
  198. "IBM 4758 CCA hardware engine support";
  199. # ifndef OPENSSL_NO_DYNAMIC_ENGINE
  200. /* Compatibility hack, the dynamic library uses this form in the path */
  201. static const char *engine_4758_cca_id_alt = "4758_cca";
  202. # endif
  203. /* engine implementation */
  204. /* ---------------------*/
  205. static int bind_helper(ENGINE *e)
  206. {
  207. if (!ENGINE_set_id(e, engine_4758_cca_id) ||
  208. !ENGINE_set_name(e, engine_4758_cca_name) ||
  209. # ifndef OPENSSL_NO_RSA
  210. !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
  211. # endif
  212. !ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
  213. !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
  214. !ENGINE_set_init_function(e, ibm_4758_cca_init) ||
  215. !ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
  216. !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
  217. # ifndef OPENSSL_NO_RSA
  218. !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
  219. !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
  220. # endif
  221. !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
  222. return 0;
  223. /* Ensure the error handling is set up */
  224. ERR_load_CCA4758_strings();
  225. return 1;
  226. }
  227. # ifdef OPENSSL_NO_DYNAMIC_ENGINE
  228. static ENGINE *engine_4758_cca(void)
  229. {
  230. ENGINE *ret = ENGINE_new();
  231. if (!ret)
  232. return NULL;
  233. if (!bind_helper(ret)) {
  234. ENGINE_free(ret);
  235. return NULL;
  236. }
  237. return ret;
  238. }
  239. void ENGINE_load_4758cca(void)
  240. {
  241. ENGINE *e_4758 = engine_4758_cca();
  242. if (!e_4758)
  243. return;
  244. ENGINE_add(e_4758);
  245. ENGINE_free(e_4758);
  246. ERR_clear_error();
  247. }
  248. # endif
  249. static int ibm_4758_cca_destroy(ENGINE *e)
  250. {
  251. ERR_unload_CCA4758_strings();
  252. free_CCA4758_LIB_NAME();
  253. return 1;
  254. }
  255. static int ibm_4758_cca_init(ENGINE *e)
  256. {
  257. if (dso) {
  258. CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED);
  259. goto err;
  260. }
  261. dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
  262. if (!dso) {
  263. CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE);
  264. goto err;
  265. }
  266. # ifndef OPENSSL_NO_RSA
  267. if (!(keyRecordRead = (F_KEYRECORDREAD)
  268. DSO_bind_func(dso, n_keyRecordRead)) ||
  269. !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
  270. DSO_bind_func(dso, n_randomNumberGenerate)) ||
  271. !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
  272. DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
  273. !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
  274. DSO_bind_func(dso, n_digitalSignatureVerify)) ||
  275. !(publicKeyExtract = (F_PUBLICKEYEXTRACT)
  276. DSO_bind_func(dso, n_publicKeyExtract)) ||
  277. !(pkaEncrypt = (F_PKAENCRYPT)
  278. DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT)
  279. DSO_bind_func(dso,
  280. n_pkaDecrypt)))
  281. {
  282. CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE);
  283. goto err;
  284. }
  285. # else
  286. if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
  287. DSO_bind_func(dso, n_randomNumberGenerate))) {
  288. CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE);
  289. goto err;
  290. }
  291. # endif
  292. # ifndef OPENSSL_NO_RSA
  293. hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
  294. NULL, NULL, cca_ex_free);
  295. # endif
  296. return 1;
  297. err:
  298. if (dso)
  299. DSO_free(dso);
  300. dso = NULL;
  301. # ifndef OPENSSL_NO_RSA
  302. keyRecordRead = (F_KEYRECORDREAD) 0;
  303. digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0;
  304. digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
  305. publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
  306. pkaEncrypt = (F_PKAENCRYPT) 0;
  307. pkaDecrypt = (F_PKADECRYPT) 0;
  308. # endif
  309. randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0;
  310. return 0;
  311. }
  312. static int ibm_4758_cca_finish(ENGINE *e)
  313. {
  314. free_CCA4758_LIB_NAME();
  315. if (!dso) {
  316. CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED);
  317. return 0;
  318. }
  319. if (!DSO_free(dso)) {
  320. CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE);
  321. return 0;
  322. }
  323. dso = NULL;
  324. # ifndef OPENSSL_NO_RSA
  325. keyRecordRead = (F_KEYRECORDREAD) 0;
  326. randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0;
  327. digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0;
  328. digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
  329. publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
  330. pkaEncrypt = (F_PKAENCRYPT) 0;
  331. pkaDecrypt = (F_PKADECRYPT) 0;
  332. # endif
  333. randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0;
  334. return 1;
  335. }
  336. static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p,
  337. void (*f) (void))
  338. {
  339. int initialised = ((dso == NULL) ? 0 : 1);
  340. switch (cmd) {
  341. case CCA4758_CMD_SO_PATH:
  342. if (p == NULL) {
  343. CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
  344. ERR_R_PASSED_NULL_PARAMETER);
  345. return 0;
  346. }
  347. if (initialised) {
  348. CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED);
  349. return 0;
  350. }
  351. return set_CCA4758_LIB_NAME((const char *)p);
  352. default:
  353. break;
  354. }
  355. CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
  356. CCA4758_R_COMMAND_NOT_IMPLEMENTED);
  357. return 0;
  358. }
  359. # ifndef OPENSSL_NO_RSA
  360. # define MAX_CCA_PKA_TOKEN_SIZE 2500
  361. static EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id,
  362. UI_METHOD *ui_method,
  363. void *callback_data)
  364. {
  365. RSA *rtmp = NULL;
  366. EVP_PKEY *res = NULL;
  367. unsigned char *keyToken = NULL;
  368. unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
  369. long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
  370. long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
  371. long returnCode;
  372. long reasonCode;
  373. long exitDataLength = 0;
  374. long ruleArrayLength = 0;
  375. unsigned char exitData[8];
  376. unsigned char ruleArray[8];
  377. unsigned char keyLabel[64];
  378. unsigned long keyLabelLength = strlen(key_id);
  379. unsigned char modulus[256];
  380. long modulusFieldLength = sizeof(modulus);
  381. long modulusLength = 0;
  382. unsigned char exponent[256];
  383. long exponentLength = sizeof(exponent);
  384. if (keyLabelLength > sizeof(keyLabel)) {
  385. CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  386. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  387. return NULL;
  388. }
  389. memset(keyLabel, ' ', sizeof(keyLabel));
  390. memcpy(keyLabel, key_id, keyLabelLength);
  391. keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
  392. if (!keyToken) {
  393. CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE);
  394. goto err;
  395. }
  396. keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
  397. exitData, &ruleArrayLength, ruleArray, keyLabel,
  398. &keyTokenLength, keyToken + sizeof(long));
  399. if (returnCode) {
  400. CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  401. CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
  402. goto err;
  403. }
  404. publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
  405. exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
  406. keyToken + sizeof(long), &pubKeyTokenLength,
  407. pubKeyToken);
  408. if (returnCode) {
  409. CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  410. CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
  411. goto err;
  412. }
  413. if (!getModulusAndExponent(pubKeyToken, &exponentLength,
  414. exponent, &modulusLength, &modulusFieldLength,
  415. modulus)) {
  416. CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  417. CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
  418. goto err;
  419. }
  420. (*(long *)keyToken) = keyTokenLength;
  421. rtmp = RSA_new_method(e);
  422. RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
  423. rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
  424. rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
  425. rtmp->flags |= RSA_FLAG_EXT_PKEY;
  426. res = EVP_PKEY_new();
  427. EVP_PKEY_assign_RSA(res, rtmp);
  428. return res;
  429. err:
  430. if (keyToken)
  431. OPENSSL_free(keyToken);
  432. return NULL;
  433. }
  434. static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id,
  435. UI_METHOD *ui_method,
  436. void *callback_data)
  437. {
  438. RSA *rtmp = NULL;
  439. EVP_PKEY *res = NULL;
  440. unsigned char *keyToken = NULL;
  441. long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
  442. long returnCode;
  443. long reasonCode;
  444. long exitDataLength = 0;
  445. long ruleArrayLength = 0;
  446. unsigned char exitData[8];
  447. unsigned char ruleArray[8];
  448. unsigned char keyLabel[64];
  449. unsigned long keyLabelLength = strlen(key_id);
  450. unsigned char modulus[512];
  451. long modulusFieldLength = sizeof(modulus);
  452. long modulusLength = 0;
  453. unsigned char exponent[512];
  454. long exponentLength = sizeof(exponent);
  455. if (keyLabelLength > sizeof(keyLabel)) {
  456. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
  457. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  458. return NULL;
  459. }
  460. memset(keyLabel, ' ', sizeof(keyLabel));
  461. memcpy(keyLabel, key_id, keyLabelLength);
  462. keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
  463. if (!keyToken) {
  464. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE);
  465. goto err;
  466. }
  467. keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
  468. &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
  469. keyToken + sizeof(long));
  470. if (returnCode) {
  471. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE);
  472. goto err;
  473. }
  474. if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength,
  475. exponent, &modulusLength, &modulusFieldLength,
  476. modulus)) {
  477. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
  478. CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
  479. goto err;
  480. }
  481. (*(long *)keyToken) = keyTokenLength;
  482. rtmp = RSA_new_method(e);
  483. RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
  484. rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
  485. rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
  486. rtmp->flags |= RSA_FLAG_EXT_PKEY;
  487. res = EVP_PKEY_new();
  488. EVP_PKEY_assign_RSA(res, rtmp);
  489. return res;
  490. err:
  491. if (keyToken)
  492. OPENSSL_free(keyToken);
  493. return NULL;
  494. }
  495. static int cca_rsa_pub_enc(int flen, const unsigned char *from,
  496. unsigned char *to, RSA *rsa, int padding)
  497. {
  498. long returnCode;
  499. long reasonCode;
  500. long lflen = flen;
  501. long exitDataLength = 0;
  502. unsigned char exitData[8];
  503. long ruleArrayLength = 1;
  504. unsigned char ruleArray[8] = "PKCS-1.2";
  505. long dataStructureLength = 0;
  506. unsigned char dataStructure[8];
  507. long outputLength = RSA_size(rsa);
  508. long keyTokenLength;
  509. unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
  510. keyTokenLength = *(long *)keyToken;
  511. keyToken += sizeof(long);
  512. pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
  513. &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from,
  514. &dataStructureLength, dataStructure, &keyTokenLength,
  515. keyToken, &outputLength, to);
  516. if (returnCode || reasonCode)
  517. return -(returnCode << 16 | reasonCode);
  518. return outputLength;
  519. }
  520. static int cca_rsa_priv_dec(int flen, const unsigned char *from,
  521. unsigned char *to, RSA *rsa, int padding)
  522. {
  523. long returnCode;
  524. long reasonCode;
  525. long lflen = flen;
  526. long exitDataLength = 0;
  527. unsigned char exitData[8];
  528. long ruleArrayLength = 1;
  529. unsigned char ruleArray[8] = "PKCS-1.2";
  530. long dataStructureLength = 0;
  531. unsigned char dataStructure[8];
  532. long outputLength = RSA_size(rsa);
  533. long keyTokenLength;
  534. unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
  535. keyTokenLength = *(long *)keyToken;
  536. keyToken += sizeof(long);
  537. pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
  538. &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from,
  539. &dataStructureLength, dataStructure, &keyTokenLength,
  540. keyToken, &outputLength, to);
  541. return (returnCode | reasonCode) ? 0 : 1;
  542. }
  543. # define SSL_SIG_LEN 36
  544. static int cca_rsa_verify(int type, const unsigned char *m,
  545. unsigned int m_len, const unsigned char *sigbuf,
  546. unsigned int siglen, const RSA *rsa)
  547. {
  548. long returnCode;
  549. long reasonCode;
  550. long lsiglen = siglen;
  551. long exitDataLength = 0;
  552. unsigned char exitData[8];
  553. long ruleArrayLength = 1;
  554. unsigned char ruleArray[8] = "PKCS-1.1";
  555. long keyTokenLength;
  556. unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
  557. long length = SSL_SIG_LEN;
  558. long keyLength;
  559. unsigned char *hashBuffer = NULL;
  560. X509_SIG sig;
  561. ASN1_TYPE parameter;
  562. X509_ALGOR algorithm;
  563. ASN1_OCTET_STRING digest;
  564. keyTokenLength = *(long *)keyToken;
  565. keyToken += sizeof(long);
  566. if (type == NID_md5 || type == NID_sha1) {
  567. sig.algor = &algorithm;
  568. algorithm.algorithm = OBJ_nid2obj(type);
  569. if (!algorithm.algorithm) {
  570. CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
  571. CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
  572. return 0;
  573. }
  574. if (!algorithm.algorithm->length) {
  575. CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
  576. CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
  577. return 0;
  578. }
  579. parameter.type = V_ASN1_NULL;
  580. parameter.value.ptr = NULL;
  581. algorithm.parameter = &parameter;
  582. sig.digest = &digest;
  583. sig.digest->data = (unsigned char *)m;
  584. sig.digest->length = m_len;
  585. length = i2d_X509_SIG(&sig, NULL);
  586. }
  587. keyLength = RSA_size(rsa);
  588. if (length - RSA_PKCS1_PADDING > keyLength) {
  589. CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
  590. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  591. return 0;
  592. }
  593. switch (type) {
  594. case NID_md5_sha1:
  595. if (m_len != SSL_SIG_LEN) {
  596. CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
  597. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  598. return 0;
  599. }
  600. hashBuffer = (unsigned char *)m;
  601. length = m_len;
  602. break;
  603. case NID_md5:
  604. {
  605. unsigned char *ptr;
  606. ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
  607. if (!hashBuffer) {
  608. CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
  609. return 0;
  610. }
  611. i2d_X509_SIG(&sig, &ptr);
  612. }
  613. break;
  614. case NID_sha1:
  615. {
  616. unsigned char *ptr;
  617. ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
  618. if (!hashBuffer) {
  619. CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
  620. return 0;
  621. }
  622. i2d_X509_SIG(&sig, &ptr);
  623. }
  624. break;
  625. default:
  626. return 0;
  627. }
  628. digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
  629. exitData, &ruleArrayLength, ruleArray,
  630. &keyTokenLength, keyToken, &length, hashBuffer,
  631. &lsiglen, (unsigned char *)sigbuf);
  632. if (type == NID_sha1 || type == NID_md5) {
  633. OPENSSL_cleanse(hashBuffer, keyLength + 1);
  634. OPENSSL_free(hashBuffer);
  635. }
  636. return ((returnCode || reasonCode) ? 0 : 1);
  637. }
  638. # define SSL_SIG_LEN 36
  639. static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
  640. unsigned char *sigret, unsigned int *siglen,
  641. const RSA *rsa)
  642. {
  643. long returnCode;
  644. long reasonCode;
  645. long exitDataLength = 0;
  646. unsigned char exitData[8];
  647. long ruleArrayLength = 1;
  648. unsigned char ruleArray[8] = "PKCS-1.1";
  649. long outputLength = 256;
  650. long outputBitLength;
  651. long keyTokenLength;
  652. unsigned char *hashBuffer = NULL;
  653. unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
  654. long length = SSL_SIG_LEN;
  655. long keyLength;
  656. X509_SIG sig;
  657. ASN1_TYPE parameter;
  658. X509_ALGOR algorithm;
  659. ASN1_OCTET_STRING digest;
  660. keyTokenLength = *(long *)keyToken;
  661. keyToken += sizeof(long);
  662. if (type == NID_md5 || type == NID_sha1) {
  663. sig.algor = &algorithm;
  664. algorithm.algorithm = OBJ_nid2obj(type);
  665. if (!algorithm.algorithm) {
  666. CCA4758err(CCA4758_F_CCA_RSA_SIGN,
  667. CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
  668. return 0;
  669. }
  670. if (!algorithm.algorithm->length) {
  671. CCA4758err(CCA4758_F_CCA_RSA_SIGN,
  672. CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
  673. return 0;
  674. }
  675. parameter.type = V_ASN1_NULL;
  676. parameter.value.ptr = NULL;
  677. algorithm.parameter = &parameter;
  678. sig.digest = &digest;
  679. sig.digest->data = (unsigned char *)m;
  680. sig.digest->length = m_len;
  681. length = i2d_X509_SIG(&sig, NULL);
  682. }
  683. keyLength = RSA_size(rsa);
  684. if (length - RSA_PKCS1_PADDING > keyLength) {
  685. CCA4758err(CCA4758_F_CCA_RSA_SIGN,
  686. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  687. return 0;
  688. }
  689. switch (type) {
  690. case NID_md5_sha1:
  691. if (m_len != SSL_SIG_LEN) {
  692. CCA4758err(CCA4758_F_CCA_RSA_SIGN,
  693. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  694. return 0;
  695. }
  696. hashBuffer = (unsigned char *)m;
  697. length = m_len;
  698. break;
  699. case NID_md5:
  700. {
  701. unsigned char *ptr;
  702. ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
  703. if (!hashBuffer) {
  704. CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE);
  705. return 0;
  706. }
  707. i2d_X509_SIG(&sig, &ptr);
  708. }
  709. break;
  710. case NID_sha1:
  711. {
  712. unsigned char *ptr;
  713. ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
  714. if (!hashBuffer) {
  715. CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE);
  716. return 0;
  717. }
  718. i2d_X509_SIG(&sig, &ptr);
  719. }
  720. break;
  721. default:
  722. return 0;
  723. }
  724. digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
  725. exitData, &ruleArrayLength, ruleArray,
  726. &keyTokenLength, keyToken, &length, hashBuffer,
  727. &outputLength, &outputBitLength, sigret);
  728. if (type == NID_sha1 || type == NID_md5) {
  729. OPENSSL_cleanse(hashBuffer, keyLength + 1);
  730. OPENSSL_free(hashBuffer);
  731. }
  732. *siglen = outputLength;
  733. return ((returnCode || reasonCode) ? 0 : 1);
  734. }
  735. static int getModulusAndExponent(const unsigned char *token,
  736. long *exponentLength,
  737. unsigned char *exponent, long *modulusLength,
  738. long *modulusFieldLength,
  739. unsigned char *modulus)
  740. {
  741. unsigned long len;
  742. if (*token++ != (char)0x1E) /* internal PKA token? */
  743. return 0;
  744. if (*token++) /* token version must be zero */
  745. return 0;
  746. len = *token++;
  747. len = len << 8;
  748. len |= (unsigned char)*token++;
  749. token += 4; /* skip reserved bytes */
  750. if (*token++ == (char)0x04) {
  751. if (*token++) /* token version must be zero */
  752. return 0;
  753. len = *token++;
  754. len = len << 8;
  755. len |= (unsigned char)*token++;
  756. token += 2; /* skip reserved section */
  757. len = *token++;
  758. len = len << 8;
  759. len |= (unsigned char)*token++;
  760. *exponentLength = len;
  761. len = *token++;
  762. len = len << 8;
  763. len |= (unsigned char)*token++;
  764. *modulusLength = len;
  765. len = *token++;
  766. len = len << 8;
  767. len |= (unsigned char)*token++;
  768. *modulusFieldLength = len;
  769. memcpy(exponent, token, *exponentLength);
  770. token += *exponentLength;
  771. memcpy(modulus, token, *modulusFieldLength);
  772. return 1;
  773. }
  774. return 0;
  775. }
  776. # endif /* OPENSSL_NO_RSA */
  777. static int cca_random_status(void)
  778. {
  779. return 1;
  780. }
  781. static int cca_get_random_bytes(unsigned char *buf, int num)
  782. {
  783. long ret_code;
  784. long reason_code;
  785. long exit_data_length;
  786. unsigned char exit_data[4];
  787. unsigned char form[] = "RANDOM ";
  788. unsigned char rand_buf[8];
  789. while (num >= (int)sizeof(rand_buf)) {
  790. randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
  791. exit_data, form, rand_buf);
  792. if (ret_code)
  793. return 0;
  794. num -= sizeof(rand_buf);
  795. memcpy(buf, rand_buf, sizeof(rand_buf));
  796. buf += sizeof(rand_buf);
  797. }
  798. if (num) {
  799. randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
  800. form, rand_buf);
  801. if (ret_code)
  802. return 0;
  803. memcpy(buf, rand_buf, num);
  804. }
  805. return 1;
  806. }
  807. # ifndef OPENSSL_NO_RSA
  808. static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
  809. long argl, void *argp)
  810. {
  811. if (item)
  812. OPENSSL_free(item);
  813. }
  814. # endif
  815. /* Goo to handle building as a dynamic engine */
  816. # ifndef OPENSSL_NO_DYNAMIC_ENGINE
  817. static int bind_fn(ENGINE *e, const char *id)
  818. {
  819. if (id && (strcmp(id, engine_4758_cca_id) != 0) &&
  820. (strcmp(id, engine_4758_cca_id_alt) != 0))
  821. return 0;
  822. if (!bind_helper(e))
  823. return 0;
  824. return 1;
  825. }
  826. IMPLEMENT_DYNAMIC_CHECK_FN()
  827. IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
  828. # endif /* OPENSSL_NO_DYNAMIC_ENGINE */
  829. # endif /* !OPENSSL_NO_HW_4758_CCA */
  830. #endif /* !OPENSSL_NO_HW */