2
0

e_4758cca.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960
  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. if (rtmp == NULL) {
  423. CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE);
  424. goto err;
  425. }
  426. RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
  427. rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
  428. rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
  429. rtmp->flags |= RSA_FLAG_EXT_PKEY;
  430. res = EVP_PKEY_new();
  431. EVP_PKEY_assign_RSA(res, rtmp);
  432. return res;
  433. err:
  434. if (keyToken)
  435. OPENSSL_free(keyToken);
  436. return NULL;
  437. }
  438. static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id,
  439. UI_METHOD *ui_method,
  440. void *callback_data)
  441. {
  442. RSA *rtmp = NULL;
  443. EVP_PKEY *res = NULL;
  444. unsigned char *keyToken = NULL;
  445. long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
  446. long returnCode;
  447. long reasonCode;
  448. long exitDataLength = 0;
  449. long ruleArrayLength = 0;
  450. unsigned char exitData[8];
  451. unsigned char ruleArray[8];
  452. unsigned char keyLabel[64];
  453. unsigned long keyLabelLength = strlen(key_id);
  454. unsigned char modulus[512];
  455. long modulusFieldLength = sizeof(modulus);
  456. long modulusLength = 0;
  457. unsigned char exponent[512];
  458. long exponentLength = sizeof(exponent);
  459. if (keyLabelLength > sizeof(keyLabel)) {
  460. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
  461. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  462. return NULL;
  463. }
  464. memset(keyLabel, ' ', sizeof(keyLabel));
  465. memcpy(keyLabel, key_id, keyLabelLength);
  466. keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
  467. if (!keyToken) {
  468. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE);
  469. goto err;
  470. }
  471. keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
  472. &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
  473. keyToken + sizeof(long));
  474. if (returnCode) {
  475. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE);
  476. goto err;
  477. }
  478. if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength,
  479. exponent, &modulusLength, &modulusFieldLength,
  480. modulus)) {
  481. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
  482. CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
  483. goto err;
  484. }
  485. (*(long *)keyToken) = keyTokenLength;
  486. rtmp = RSA_new_method(e);
  487. if (rtmp == NULL) {
  488. CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE);
  489. goto err;
  490. }
  491. RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
  492. rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
  493. rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
  494. rtmp->flags |= RSA_FLAG_EXT_PKEY;
  495. res = EVP_PKEY_new();
  496. EVP_PKEY_assign_RSA(res, rtmp);
  497. return res;
  498. err:
  499. if (keyToken)
  500. OPENSSL_free(keyToken);
  501. return NULL;
  502. }
  503. static int cca_rsa_pub_enc(int flen, const unsigned char *from,
  504. unsigned char *to, RSA *rsa, int padding)
  505. {
  506. long returnCode;
  507. long reasonCode;
  508. long lflen = flen;
  509. long exitDataLength = 0;
  510. unsigned char exitData[8];
  511. long ruleArrayLength = 1;
  512. unsigned char ruleArray[8] = "PKCS-1.2";
  513. long dataStructureLength = 0;
  514. unsigned char dataStructure[8];
  515. long outputLength = RSA_size(rsa);
  516. long keyTokenLength;
  517. unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
  518. keyTokenLength = *(long *)keyToken;
  519. keyToken += sizeof(long);
  520. pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
  521. &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from,
  522. &dataStructureLength, dataStructure, &keyTokenLength,
  523. keyToken, &outputLength, to);
  524. if (returnCode || reasonCode)
  525. return -(returnCode << 16 | reasonCode);
  526. return outputLength;
  527. }
  528. static int cca_rsa_priv_dec(int flen, const unsigned char *from,
  529. unsigned char *to, RSA *rsa, int padding)
  530. {
  531. long returnCode;
  532. long reasonCode;
  533. long lflen = flen;
  534. long exitDataLength = 0;
  535. unsigned char exitData[8];
  536. long ruleArrayLength = 1;
  537. unsigned char ruleArray[8] = "PKCS-1.2";
  538. long dataStructureLength = 0;
  539. unsigned char dataStructure[8];
  540. long outputLength = RSA_size(rsa);
  541. long keyTokenLength;
  542. unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
  543. keyTokenLength = *(long *)keyToken;
  544. keyToken += sizeof(long);
  545. pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
  546. &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from,
  547. &dataStructureLength, dataStructure, &keyTokenLength,
  548. keyToken, &outputLength, to);
  549. return (returnCode | reasonCode) ? 0 : 1;
  550. }
  551. # define SSL_SIG_LEN 36
  552. static int cca_rsa_verify(int type, const unsigned char *m,
  553. unsigned int m_len, const unsigned char *sigbuf,
  554. unsigned int siglen, const RSA *rsa)
  555. {
  556. long returnCode;
  557. long reasonCode;
  558. long lsiglen = siglen;
  559. long exitDataLength = 0;
  560. unsigned char exitData[8];
  561. long ruleArrayLength = 1;
  562. unsigned char ruleArray[8] = "PKCS-1.1";
  563. long keyTokenLength;
  564. unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
  565. long length = SSL_SIG_LEN;
  566. long keyLength;
  567. unsigned char *hashBuffer = NULL;
  568. X509_SIG sig;
  569. ASN1_TYPE parameter;
  570. X509_ALGOR algorithm;
  571. ASN1_OCTET_STRING digest;
  572. keyTokenLength = *(long *)keyToken;
  573. keyToken += sizeof(long);
  574. if (type == NID_md5 || type == NID_sha1) {
  575. sig.algor = &algorithm;
  576. algorithm.algorithm = OBJ_nid2obj(type);
  577. if (!algorithm.algorithm) {
  578. CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
  579. CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
  580. return 0;
  581. }
  582. if (!algorithm.algorithm->length) {
  583. CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
  584. CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
  585. return 0;
  586. }
  587. parameter.type = V_ASN1_NULL;
  588. parameter.value.ptr = NULL;
  589. algorithm.parameter = &parameter;
  590. sig.digest = &digest;
  591. sig.digest->data = (unsigned char *)m;
  592. sig.digest->length = m_len;
  593. length = i2d_X509_SIG(&sig, NULL);
  594. }
  595. keyLength = RSA_size(rsa);
  596. if (length - RSA_PKCS1_PADDING > keyLength) {
  597. CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
  598. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  599. return 0;
  600. }
  601. switch (type) {
  602. case NID_md5_sha1:
  603. if (m_len != SSL_SIG_LEN) {
  604. CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
  605. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  606. return 0;
  607. }
  608. hashBuffer = (unsigned char *)m;
  609. length = m_len;
  610. break;
  611. case NID_md5:
  612. {
  613. unsigned char *ptr;
  614. ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
  615. if (!hashBuffer) {
  616. CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
  617. return 0;
  618. }
  619. i2d_X509_SIG(&sig, &ptr);
  620. }
  621. break;
  622. case NID_sha1:
  623. {
  624. unsigned char *ptr;
  625. ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
  626. if (!hashBuffer) {
  627. CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
  628. return 0;
  629. }
  630. i2d_X509_SIG(&sig, &ptr);
  631. }
  632. break;
  633. default:
  634. return 0;
  635. }
  636. digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
  637. exitData, &ruleArrayLength, ruleArray,
  638. &keyTokenLength, keyToken, &length, hashBuffer,
  639. &lsiglen, (unsigned char *)sigbuf);
  640. if (type == NID_sha1 || type == NID_md5) {
  641. OPENSSL_cleanse(hashBuffer, keyLength + 1);
  642. OPENSSL_free(hashBuffer);
  643. }
  644. return ((returnCode || reasonCode) ? 0 : 1);
  645. }
  646. # define SSL_SIG_LEN 36
  647. static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
  648. unsigned char *sigret, unsigned int *siglen,
  649. const RSA *rsa)
  650. {
  651. long returnCode;
  652. long reasonCode;
  653. long exitDataLength = 0;
  654. unsigned char exitData[8];
  655. long ruleArrayLength = 1;
  656. unsigned char ruleArray[8] = "PKCS-1.1";
  657. long outputLength = 256;
  658. long outputBitLength;
  659. long keyTokenLength;
  660. unsigned char *hashBuffer = NULL;
  661. unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
  662. long length = SSL_SIG_LEN;
  663. long keyLength;
  664. X509_SIG sig;
  665. ASN1_TYPE parameter;
  666. X509_ALGOR algorithm;
  667. ASN1_OCTET_STRING digest;
  668. keyTokenLength = *(long *)keyToken;
  669. keyToken += sizeof(long);
  670. if (type == NID_md5 || type == NID_sha1) {
  671. sig.algor = &algorithm;
  672. algorithm.algorithm = OBJ_nid2obj(type);
  673. if (!algorithm.algorithm) {
  674. CCA4758err(CCA4758_F_CCA_RSA_SIGN,
  675. CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
  676. return 0;
  677. }
  678. if (!algorithm.algorithm->length) {
  679. CCA4758err(CCA4758_F_CCA_RSA_SIGN,
  680. CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
  681. return 0;
  682. }
  683. parameter.type = V_ASN1_NULL;
  684. parameter.value.ptr = NULL;
  685. algorithm.parameter = &parameter;
  686. sig.digest = &digest;
  687. sig.digest->data = (unsigned char *)m;
  688. sig.digest->length = m_len;
  689. length = i2d_X509_SIG(&sig, NULL);
  690. }
  691. keyLength = RSA_size(rsa);
  692. if (length - RSA_PKCS1_PADDING > keyLength) {
  693. CCA4758err(CCA4758_F_CCA_RSA_SIGN,
  694. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  695. return 0;
  696. }
  697. switch (type) {
  698. case NID_md5_sha1:
  699. if (m_len != SSL_SIG_LEN) {
  700. CCA4758err(CCA4758_F_CCA_RSA_SIGN,
  701. CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  702. return 0;
  703. }
  704. hashBuffer = (unsigned char *)m;
  705. length = m_len;
  706. break;
  707. case NID_md5:
  708. {
  709. unsigned char *ptr;
  710. ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
  711. if (!hashBuffer) {
  712. CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE);
  713. return 0;
  714. }
  715. i2d_X509_SIG(&sig, &ptr);
  716. }
  717. break;
  718. case NID_sha1:
  719. {
  720. unsigned char *ptr;
  721. ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
  722. if (!hashBuffer) {
  723. CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE);
  724. return 0;
  725. }
  726. i2d_X509_SIG(&sig, &ptr);
  727. }
  728. break;
  729. default:
  730. return 0;
  731. }
  732. digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
  733. exitData, &ruleArrayLength, ruleArray,
  734. &keyTokenLength, keyToken, &length, hashBuffer,
  735. &outputLength, &outputBitLength, sigret);
  736. if (type == NID_sha1 || type == NID_md5) {
  737. OPENSSL_cleanse(hashBuffer, keyLength + 1);
  738. OPENSSL_free(hashBuffer);
  739. }
  740. *siglen = outputLength;
  741. return ((returnCode || reasonCode) ? 0 : 1);
  742. }
  743. static int getModulusAndExponent(const unsigned char *token,
  744. long *exponentLength,
  745. unsigned char *exponent, long *modulusLength,
  746. long *modulusFieldLength,
  747. unsigned char *modulus)
  748. {
  749. unsigned long len;
  750. if (*token++ != (char)0x1E) /* internal PKA token? */
  751. return 0;
  752. if (*token++) /* token version must be zero */
  753. return 0;
  754. len = *token++;
  755. len = len << 8;
  756. len |= (unsigned char)*token++;
  757. token += 4; /* skip reserved bytes */
  758. if (*token++ == (char)0x04) {
  759. if (*token++) /* token version must be zero */
  760. return 0;
  761. len = *token++;
  762. len = len << 8;
  763. len |= (unsigned char)*token++;
  764. token += 2; /* skip reserved section */
  765. len = *token++;
  766. len = len << 8;
  767. len |= (unsigned char)*token++;
  768. *exponentLength = len;
  769. len = *token++;
  770. len = len << 8;
  771. len |= (unsigned char)*token++;
  772. *modulusLength = len;
  773. len = *token++;
  774. len = len << 8;
  775. len |= (unsigned char)*token++;
  776. *modulusFieldLength = len;
  777. memcpy(exponent, token, *exponentLength);
  778. token += *exponentLength;
  779. memcpy(modulus, token, *modulusFieldLength);
  780. return 1;
  781. }
  782. return 0;
  783. }
  784. # endif /* OPENSSL_NO_RSA */
  785. static int cca_random_status(void)
  786. {
  787. return 1;
  788. }
  789. static int cca_get_random_bytes(unsigned char *buf, int num)
  790. {
  791. long ret_code;
  792. long reason_code;
  793. long exit_data_length;
  794. unsigned char exit_data[4];
  795. unsigned char form[] = "RANDOM ";
  796. unsigned char rand_buf[8];
  797. while (num >= (int)sizeof(rand_buf)) {
  798. randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
  799. exit_data, form, rand_buf);
  800. if (ret_code)
  801. return 0;
  802. num -= sizeof(rand_buf);
  803. memcpy(buf, rand_buf, sizeof(rand_buf));
  804. buf += sizeof(rand_buf);
  805. }
  806. if (num) {
  807. randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
  808. form, rand_buf);
  809. if (ret_code)
  810. return 0;
  811. memcpy(buf, rand_buf, num);
  812. }
  813. return 1;
  814. }
  815. # ifndef OPENSSL_NO_RSA
  816. static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
  817. long argl, void *argp)
  818. {
  819. if (item)
  820. OPENSSL_free(item);
  821. }
  822. # endif
  823. /* Goo to handle building as a dynamic engine */
  824. # ifndef OPENSSL_NO_DYNAMIC_ENGINE
  825. static int bind_fn(ENGINE *e, const char *id)
  826. {
  827. if (id && (strcmp(id, engine_4758_cca_id) != 0) &&
  828. (strcmp(id, engine_4758_cca_id_alt) != 0))
  829. return 0;
  830. if (!bind_helper(e))
  831. return 0;
  832. return 1;
  833. }
  834. IMPLEMENT_DYNAMIC_CHECK_FN()
  835. IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
  836. # endif /* OPENSSL_NO_DYNAMIC_ENGINE */
  837. # endif /* !OPENSSL_NO_HW_4758_CCA */
  838. #endif /* !OPENSSL_NO_HW */