PageRenderTime 395ms CodeModel.GetById 50ms RepoModel.GetById 5ms app.codeStats 2ms

/security/nss/lib/softoken/pkcs11c.c

http://github.com/zpao/v8monkey
C | 6575 lines | 5055 code | 667 blank | 853 comment | 1325 complexity | dc7e5c203f1d91eb1f4d216671ed2d02 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, LGPL-2.1, BSD-3-Clause, GPL-2.0, JSON, Apache-2.0, 0BSD
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is the Netscape security libraries.
  15. *
  16. * The Initial Developer of the Original Code is
  17. * Netscape Communications Corporation.
  18. * Portions created by the Initial Developer are Copyright (C) 1994-2000
  19. * the Initial Developer. All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. * Dr Stephen Henson <stephen.henson@gemplus.com>
  23. * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
  24. *
  25. * Alternatively, the contents of this file may be used under the terms of
  26. * either the GNU General Public License Version 2 or later (the "GPL"), or
  27. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28. * in which case the provisions of the GPL or the LGPL are applicable instead
  29. * of those above. If you wish to allow use of your version of this file only
  30. * under the terms of either the GPL or the LGPL, and not to allow others to
  31. * use your version of this file under the terms of the MPL, indicate your
  32. * decision by deleting the provisions above and replace them with the notice
  33. * and other provisions required by the GPL or the LGPL. If you do not delete
  34. * the provisions above, a recipient may use your version of this file under
  35. * the terms of any one of the MPL, the GPL or the LGPL.
  36. *
  37. * ***** END LICENSE BLOCK ***** */
  38. /*
  39. * This file implements PKCS 11 on top of our existing security modules
  40. *
  41. * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
  42. * This implementation has two slots:
  43. * slot 1 is our generic crypto support. It does not require login.
  44. * It supports Public Key ops, and all they bulk ciphers and hashes.
  45. * It can also support Private Key ops for imported Private keys. It does
  46. * not have any token storage.
  47. * slot 2 is our private key support. It requires a login before use. It
  48. * can store Private Keys and Certs as token objects. Currently only private
  49. * keys and their associated Certificates are saved on the token.
  50. *
  51. * In this implementation, session objects are only visible to the session
  52. * that created or generated them.
  53. */
  54. #include "seccomon.h"
  55. #include "secitem.h"
  56. #include "secport.h"
  57. #include "blapi.h"
  58. #include "pkcs11.h"
  59. #include "pkcs11i.h"
  60. #include "lowkeyi.h"
  61. #include "sechash.h"
  62. #include "secder.h"
  63. #include "secdig.h"
  64. #include "lowpbe.h" /* We do PBE below */
  65. #include "pkcs11t.h"
  66. #include "secoid.h"
  67. #include "alghmac.h"
  68. #include "softoken.h"
  69. #include "secasn1.h"
  70. #include "secerr.h"
  71. #include "prprf.h"
  72. #define __PASTE(x,y) x##y
  73. /*
  74. * we renamed all our internal functions, get the correct
  75. * definitions for them...
  76. */
  77. #undef CK_PKCS11_FUNCTION_INFO
  78. #undef CK_NEED_ARG_LIST
  79. #define CK_EXTERN extern
  80. #define CK_PKCS11_FUNCTION_INFO(func) \
  81. CK_RV __PASTE(NS,func)
  82. #define CK_NEED_ARG_LIST 1
  83. #include "pkcs11f.h"
  84. typedef struct {
  85. uint8 client_version[2];
  86. uint8 random[46];
  87. } SSL3RSAPreMasterSecret;
  88. static void sftk_Null(void *data, PRBool freeit)
  89. {
  90. return;
  91. }
  92. #ifdef NSS_ENABLE_ECC
  93. #ifdef EC_DEBUG
  94. #define SEC_PRINT(str1, str2, num, sitem) \
  95. printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \
  96. str1, str2, num, sitem->len); \
  97. for (i = 0; i < sitem->len; i++) { \
  98. printf("%02x:", sitem->data[i]); \
  99. } \
  100. printf("\n")
  101. #else
  102. #define SEC_PRINT(a, b, c, d)
  103. #endif
  104. #endif /* NSS_ENABLE_ECC */
  105. /*
  106. * free routines.... Free local type allocated data, and convert
  107. * other free routines to the destroy signature.
  108. */
  109. static void
  110. sftk_FreePrivKey(NSSLOWKEYPrivateKey *key, PRBool freeit)
  111. {
  112. nsslowkey_DestroyPrivateKey(key);
  113. }
  114. static void
  115. sftk_Space(void *data, PRBool freeit)
  116. {
  117. PORT_Free(data);
  118. }
  119. /*
  120. * map all the SEC_ERROR_xxx error codes that may be returned by freebl
  121. * functions to CKR_xxx. return CKR_DEVICE_ERROR by default for backward
  122. * compatibility.
  123. */
  124. static CK_RV
  125. sftk_MapCryptError(int error)
  126. {
  127. switch (error) {
  128. case SEC_ERROR_INVALID_ARGS:
  129. case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */
  130. return CKR_ARGUMENTS_BAD;
  131. case SEC_ERROR_INPUT_LEN:
  132. return CKR_DATA_LEN_RANGE;
  133. case SEC_ERROR_OUTPUT_LEN:
  134. return CKR_BUFFER_TOO_SMALL;
  135. case SEC_ERROR_LIBRARY_FAILURE:
  136. return CKR_GENERAL_ERROR;
  137. case SEC_ERROR_NO_MEMORY:
  138. return CKR_HOST_MEMORY;
  139. case SEC_ERROR_BAD_SIGNATURE:
  140. return CKR_SIGNATURE_INVALID;
  141. case SEC_ERROR_INVALID_KEY:
  142. return CKR_KEY_SIZE_RANGE;
  143. case SEC_ERROR_BAD_KEY: /* an EC public key that fails validation */
  144. return CKR_KEY_SIZE_RANGE; /* the closest error code */
  145. case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM:
  146. return CKR_TEMPLATE_INCONSISTENT;
  147. /* EC functions set this error if NSS_ENABLE_ECC is not defined */
  148. case SEC_ERROR_UNSUPPORTED_KEYALG:
  149. return CKR_MECHANISM_INVALID;
  150. case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE:
  151. return CKR_DOMAIN_PARAMS_INVALID;
  152. /* key pair generation failed after max number of attempts */
  153. case SEC_ERROR_NEED_RANDOM:
  154. return CKR_FUNCTION_FAILED;
  155. }
  156. return CKR_DEVICE_ERROR;
  157. }
  158. /* used by Decrypt and UnwrapKey (indirectly) */
  159. static CK_RV
  160. sftk_MapDecryptError(int error)
  161. {
  162. switch (error) {
  163. case SEC_ERROR_BAD_DATA:
  164. return CKR_ENCRYPTED_DATA_INVALID;
  165. default:
  166. return sftk_MapCryptError(error);
  167. }
  168. }
  169. /*
  170. * return CKR_SIGNATURE_INVALID instead of CKR_DEVICE_ERROR by default for
  171. * backward compatibilty.
  172. */
  173. static CK_RV
  174. sftk_MapVerifyError(int error)
  175. {
  176. CK_RV crv = sftk_MapCryptError(error);
  177. if (crv == CKR_DEVICE_ERROR)
  178. crv = CKR_SIGNATURE_INVALID;
  179. return crv;
  180. }
  181. /*
  182. * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by
  183. * Deprecating a full des key to 40 bit key strenth.
  184. */
  185. static CK_RV
  186. sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
  187. {
  188. unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae };
  189. unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 };
  190. unsigned char enc_src[8];
  191. unsigned char enc_dest[8];
  192. unsigned int leng,i;
  193. DESContext *descx;
  194. SECStatus rv;
  195. /* zero the parity bits */
  196. for (i=0; i < 8; i++) {
  197. enc_src[i] = cdmfkey[i] & 0xfe;
  198. }
  199. /* encrypt with key 1 */
  200. descx = DES_CreateContext(key1, NULL, NSS_DES, PR_TRUE);
  201. if (descx == NULL) return CKR_HOST_MEMORY;
  202. rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8);
  203. DES_DestroyContext(descx,PR_TRUE);
  204. if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError());
  205. /* xor source with des, zero the parity bits and deprecate the key*/
  206. for (i=0; i < 8; i++) {
  207. if (i & 1) {
  208. enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe;
  209. } else {
  210. enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e;
  211. }
  212. }
  213. /* encrypt with key 2 */
  214. descx = DES_CreateContext(key2, NULL, NSS_DES, PR_TRUE);
  215. if (descx == NULL) return CKR_HOST_MEMORY;
  216. rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8);
  217. DES_DestroyContext(descx,PR_TRUE);
  218. if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError());
  219. /* set the corret parity on our new des key */
  220. sftk_FormatDESKey(deskey, 8);
  221. return CKR_OK;
  222. }
  223. /* NSC_DestroyObject destroys an object. */
  224. CK_RV
  225. NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
  226. {
  227. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  228. SFTKSession *session;
  229. SFTKObject *object;
  230. SFTKFreeStatus status;
  231. CHECK_FORK();
  232. if (slot == NULL) {
  233. return CKR_SESSION_HANDLE_INVALID;
  234. }
  235. /*
  236. * This whole block just makes sure we really can destroy the
  237. * requested object.
  238. */
  239. session = sftk_SessionFromHandle(hSession);
  240. if (session == NULL) {
  241. return CKR_SESSION_HANDLE_INVALID;
  242. }
  243. object = sftk_ObjectFromHandle(hObject,session);
  244. if (object == NULL) {
  245. sftk_FreeSession(session);
  246. return CKR_OBJECT_HANDLE_INVALID;
  247. }
  248. /* don't destroy a private object if we aren't logged in */
  249. if ((!slot->isLoggedIn) && (slot->needLogin) &&
  250. (sftk_isTrue(object,CKA_PRIVATE))) {
  251. sftk_FreeSession(session);
  252. sftk_FreeObject(object);
  253. return CKR_USER_NOT_LOGGED_IN;
  254. }
  255. /* don't destroy a token object if we aren't in a rw session */
  256. if (((session->info.flags & CKF_RW_SESSION) == 0) &&
  257. (sftk_isTrue(object,CKA_TOKEN))) {
  258. sftk_FreeSession(session);
  259. sftk_FreeObject(object);
  260. return CKR_SESSION_READ_ONLY;
  261. }
  262. sftk_DeleteObject(session,object);
  263. sftk_FreeSession(session);
  264. /*
  265. * get some indication if the object is destroyed. Note: this is not
  266. * 100%. Someone may have an object reference outstanding (though that
  267. * should not be the case by here. Also note that the object is "half"
  268. * destroyed. Our internal representation is destroyed, but it may still
  269. * be in the data base.
  270. */
  271. status = sftk_FreeObject(object);
  272. return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR;
  273. }
  274. /*
  275. ************** Crypto Functions: Utilities ************************
  276. */
  277. /*
  278. * return a context based on the SFTKContext type.
  279. */
  280. SFTKSessionContext *
  281. sftk_ReturnContextByType(SFTKSession *session, SFTKContextType type)
  282. {
  283. switch (type) {
  284. case SFTK_ENCRYPT:
  285. case SFTK_DECRYPT:
  286. return session->enc_context;
  287. case SFTK_HASH:
  288. return session->hash_context;
  289. case SFTK_SIGN:
  290. case SFTK_SIGN_RECOVER:
  291. case SFTK_VERIFY:
  292. case SFTK_VERIFY_RECOVER:
  293. return session->hash_context;
  294. }
  295. return NULL;
  296. }
  297. /*
  298. * change a context based on the SFTKContext type.
  299. */
  300. void
  301. sftk_SetContextByType(SFTKSession *session, SFTKContextType type,
  302. SFTKSessionContext *context)
  303. {
  304. switch (type) {
  305. case SFTK_ENCRYPT:
  306. case SFTK_DECRYPT:
  307. session->enc_context = context;
  308. break;
  309. case SFTK_HASH:
  310. session->hash_context = context;
  311. break;
  312. case SFTK_SIGN:
  313. case SFTK_SIGN_RECOVER:
  314. case SFTK_VERIFY:
  315. case SFTK_VERIFY_RECOVER:
  316. session->hash_context = context;
  317. break;
  318. }
  319. return;
  320. }
  321. /*
  322. * code to grab the context. Needed by every C_XXXUpdate, C_XXXFinal,
  323. * and C_XXX function. The function takes a session handle, the context type,
  324. * and wether or not the session needs to be multipart. It returns the context,
  325. * and optionally returns the session pointer (if sessionPtr != NULL) if session
  326. * pointer is returned, the caller is responsible for freeing it.
  327. */
  328. static CK_RV
  329. sftk_GetContext(CK_SESSION_HANDLE handle,SFTKSessionContext **contextPtr,
  330. SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr)
  331. {
  332. SFTKSession *session;
  333. SFTKSessionContext *context;
  334. session = sftk_SessionFromHandle(handle);
  335. if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
  336. context = sftk_ReturnContextByType(session,type);
  337. /* make sure the context is valid */
  338. if((context==NULL)||(context->type!=type)||(needMulti&&!(context->multi))){
  339. sftk_FreeSession(session);
  340. return CKR_OPERATION_NOT_INITIALIZED;
  341. }
  342. *contextPtr = context;
  343. if (sessionPtr != NULL) {
  344. *sessionPtr = session;
  345. } else {
  346. sftk_FreeSession(session);
  347. }
  348. return CKR_OK;
  349. }
  350. /** Terminate operation (in the PKCS#11 spec sense).
  351. * Intuitive name for FreeContext/SetNullContext pair.
  352. */
  353. static void
  354. sftk_TerminateOp( SFTKSession *session, SFTKContextType ctype,
  355. SFTKSessionContext *context )
  356. {
  357. sftk_FreeContext( context );
  358. sftk_SetContextByType( session, ctype, NULL );
  359. }
  360. /*
  361. ************** Crypto Functions: Encrypt ************************
  362. */
  363. /*
  364. * All the NSC_InitXXX functions have a set of common checks and processing they
  365. * all need to do at the beginning. This is done here.
  366. */
  367. static CK_RV
  368. sftk_InitGeneric(SFTKSession *session,SFTKSessionContext **contextPtr,
  369. SFTKContextType ctype,SFTKObject **keyPtr,
  370. CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr,
  371. CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation)
  372. {
  373. SFTKObject *key = NULL;
  374. SFTKAttribute *att;
  375. SFTKSessionContext *context;
  376. /* We can only init if there is not current context active */
  377. if (sftk_ReturnContextByType(session,ctype) != NULL) {
  378. return CKR_OPERATION_ACTIVE;
  379. }
  380. /* find the key */
  381. if (keyPtr) {
  382. key = sftk_ObjectFromHandle(hKey,session);
  383. if (key == NULL) {
  384. return CKR_KEY_HANDLE_INVALID;
  385. }
  386. /* make sure it's a valid key for this operation */
  387. if (((key->objclass != CKO_SECRET_KEY) && (key->objclass != pubKeyType))
  388. || !sftk_isTrue(key,operation)) {
  389. sftk_FreeObject(key);
  390. return CKR_KEY_TYPE_INCONSISTENT;
  391. }
  392. /* get the key type */
  393. att = sftk_FindAttribute(key,CKA_KEY_TYPE);
  394. if (att == NULL) {
  395. sftk_FreeObject(key);
  396. return CKR_KEY_TYPE_INCONSISTENT;
  397. }
  398. PORT_Assert(att->attrib.ulValueLen == sizeof(CK_KEY_TYPE));
  399. if (att->attrib.ulValueLen != sizeof(CK_KEY_TYPE)) {
  400. sftk_FreeAttribute(att);
  401. sftk_FreeObject(key);
  402. return CKR_ATTRIBUTE_VALUE_INVALID;
  403. }
  404. PORT_Memcpy(keyTypePtr, att->attrib.pValue, sizeof(CK_KEY_TYPE));
  405. sftk_FreeAttribute(att);
  406. *keyPtr = key;
  407. }
  408. /* allocate the context structure */
  409. context = (SFTKSessionContext *)PORT_Alloc(sizeof(SFTKSessionContext));
  410. if (context == NULL) {
  411. if (key) sftk_FreeObject(key);
  412. return CKR_HOST_MEMORY;
  413. }
  414. context->type = ctype;
  415. context->multi = PR_TRUE;
  416. context->cipherInfo = NULL;
  417. context->hashInfo = NULL;
  418. context->doPad = PR_FALSE;
  419. context->padDataLength = 0;
  420. context->key = key;
  421. context->blockSize = 0;
  422. *contextPtr = context;
  423. return CKR_OK;
  424. }
  425. /** NSC_CryptInit initializes an encryption/Decryption operation.
  426. *
  427. * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
  428. * Called by NSC_SignInit, NSC_VerifyInit (via sftk_InitCBCMac) only for block
  429. * ciphers MAC'ing.
  430. */
  431. static CK_RV
  432. sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
  433. CK_OBJECT_HANDLE hKey,
  434. CK_ATTRIBUTE_TYPE mechUsage, CK_ATTRIBUTE_TYPE keyUsage,
  435. SFTKContextType contextType, PRBool isEncrypt)
  436. {
  437. SFTKSession *session;
  438. SFTKObject *key;
  439. SFTKSessionContext *context;
  440. SFTKAttribute *att;
  441. CK_RC2_CBC_PARAMS *rc2_param;
  442. #if NSS_SOFTOKEN_DOES_RC5
  443. CK_RC5_CBC_PARAMS *rc5_param;
  444. SECItem rc5Key;
  445. #endif
  446. CK_KEY_TYPE key_type;
  447. CK_RV crv = CKR_OK;
  448. unsigned effectiveKeyLength;
  449. unsigned char newdeskey[24];
  450. PRBool useNewKey=PR_FALSE;
  451. int t;
  452. crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage );
  453. if (crv != CKR_OK)
  454. return crv;
  455. session = sftk_SessionFromHandle(hSession);
  456. if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
  457. crv = sftk_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
  458. isEncrypt ?CKO_PUBLIC_KEY:CKO_PRIVATE_KEY, keyUsage);
  459. if (crv != CKR_OK) {
  460. sftk_FreeSession(session);
  461. return crv;
  462. }
  463. context->doPad = PR_FALSE;
  464. switch(pMechanism->mechanism) {
  465. case CKM_RSA_PKCS:
  466. case CKM_RSA_X_509:
  467. if (key_type != CKK_RSA) {
  468. crv = CKR_KEY_TYPE_INCONSISTENT;
  469. break;
  470. }
  471. context->multi = PR_FALSE;
  472. if (isEncrypt) {
  473. NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
  474. if (pubKey == NULL) {
  475. break;
  476. }
  477. context->maxLen = nsslowkey_PublicModulusLen(pubKey);
  478. context->cipherInfo = (void *)pubKey;
  479. context->update = (SFTKCipher)
  480. (pMechanism->mechanism == CKM_RSA_X_509
  481. ? RSA_EncryptRaw : RSA_EncryptBlock);
  482. } else {
  483. NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
  484. if (privKey == NULL) {
  485. break;
  486. }
  487. context->maxLen = nsslowkey_PrivateModulusLen(privKey);
  488. context->cipherInfo = (void *)privKey;
  489. context->update = (SFTKCipher)
  490. (pMechanism->mechanism == CKM_RSA_X_509
  491. ? RSA_DecryptRaw : RSA_DecryptBlock);
  492. }
  493. context->destroy = sftk_Null;
  494. break;
  495. case CKM_RC2_CBC_PAD:
  496. context->doPad = PR_TRUE;
  497. /* fall thru */
  498. case CKM_RC2_ECB:
  499. case CKM_RC2_CBC:
  500. context->blockSize = 8;
  501. if (key_type != CKK_RC2) {
  502. crv = CKR_KEY_TYPE_INCONSISTENT;
  503. break;
  504. }
  505. att = sftk_FindAttribute(key,CKA_VALUE);
  506. if (att == NULL) {
  507. crv = CKR_KEY_HANDLE_INVALID;
  508. break;
  509. }
  510. rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
  511. effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8;
  512. context->cipherInfo =
  513. RC2_CreateContext((unsigned char*)att->attrib.pValue,
  514. att->attrib.ulValueLen, rc2_param->iv,
  515. pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 :
  516. NSS_RC2_CBC,effectiveKeyLength);
  517. sftk_FreeAttribute(att);
  518. if (context->cipherInfo == NULL) {
  519. crv = CKR_HOST_MEMORY;
  520. break;
  521. }
  522. context->update = (SFTKCipher) (isEncrypt ? RC2_Encrypt : RC2_Decrypt);
  523. context->destroy = (SFTKDestroy) RC2_DestroyContext;
  524. break;
  525. #if NSS_SOFTOKEN_DOES_RC5
  526. case CKM_RC5_CBC_PAD:
  527. context->doPad = PR_TRUE;
  528. /* fall thru */
  529. case CKM_RC5_ECB:
  530. case CKM_RC5_CBC:
  531. if (key_type != CKK_RC5) {
  532. crv = CKR_KEY_TYPE_INCONSISTENT;
  533. break;
  534. }
  535. att = sftk_FindAttribute(key,CKA_VALUE);
  536. if (att == NULL) {
  537. crv = CKR_KEY_HANDLE_INVALID;
  538. break;
  539. }
  540. rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
  541. context->blockSize = rc5_param->ulWordsize*2;
  542. rc5Key.data = (unsigned char*)att->attrib.pValue;
  543. rc5Key.len = att->attrib.ulValueLen;
  544. context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds,
  545. rc5_param->ulWordsize,rc5_param->pIv,
  546. pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC);
  547. sftk_FreeAttribute(att);
  548. if (context->cipherInfo == NULL) {
  549. crv = CKR_HOST_MEMORY;
  550. break;
  551. }
  552. context->update = (SFTKCipher) (isEncrypt ? RC5_Encrypt : RC5_Decrypt);
  553. context->destroy = (SFTKDestroy) RC5_DestroyContext;
  554. break;
  555. #endif
  556. case CKM_RC4:
  557. if (key_type != CKK_RC4) {
  558. crv = CKR_KEY_TYPE_INCONSISTENT;
  559. break;
  560. }
  561. att = sftk_FindAttribute(key,CKA_VALUE);
  562. if (att == NULL) {
  563. crv = CKR_KEY_HANDLE_INVALID;
  564. break;
  565. }
  566. context->cipherInfo =
  567. RC4_CreateContext((unsigned char*)att->attrib.pValue,
  568. att->attrib.ulValueLen);
  569. sftk_FreeAttribute(att);
  570. if (context->cipherInfo == NULL) {
  571. crv = CKR_HOST_MEMORY; /* WRONG !!! */
  572. break;
  573. }
  574. context->update = (SFTKCipher) (isEncrypt ? RC4_Encrypt : RC4_Decrypt);
  575. context->destroy = (SFTKDestroy) RC4_DestroyContext;
  576. break;
  577. case CKM_CDMF_CBC_PAD:
  578. context->doPad = PR_TRUE;
  579. /* fall thru */
  580. case CKM_CDMF_ECB:
  581. case CKM_CDMF_CBC:
  582. if (key_type != CKK_CDMF) {
  583. crv = CKR_KEY_TYPE_INCONSISTENT;
  584. break;
  585. }
  586. t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
  587. if (crv != CKR_OK) break;
  588. goto finish_des;
  589. case CKM_DES_ECB:
  590. if (key_type != CKK_DES) {
  591. crv = CKR_KEY_TYPE_INCONSISTENT;
  592. break;
  593. }
  594. t = NSS_DES;
  595. goto finish_des;
  596. case CKM_DES_CBC_PAD:
  597. context->doPad = PR_TRUE;
  598. /* fall thru */
  599. case CKM_DES_CBC:
  600. if (key_type != CKK_DES) {
  601. crv = CKR_KEY_TYPE_INCONSISTENT;
  602. break;
  603. }
  604. t = NSS_DES_CBC;
  605. goto finish_des;
  606. case CKM_DES3_ECB:
  607. if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
  608. crv = CKR_KEY_TYPE_INCONSISTENT;
  609. break;
  610. }
  611. t = NSS_DES_EDE3;
  612. goto finish_des;
  613. case CKM_DES3_CBC_PAD:
  614. context->doPad = PR_TRUE;
  615. /* fall thru */
  616. case CKM_DES3_CBC:
  617. if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
  618. crv = CKR_KEY_TYPE_INCONSISTENT;
  619. break;
  620. }
  621. t = NSS_DES_EDE3_CBC;
  622. finish_des:
  623. context->blockSize = 8;
  624. att = sftk_FindAttribute(key,CKA_VALUE);
  625. if (att == NULL) {
  626. crv = CKR_KEY_HANDLE_INVALID;
  627. break;
  628. }
  629. if (key_type == CKK_DES2 &&
  630. (t == NSS_DES_EDE3_CBC || t == NSS_DES_EDE3)) {
  631. /* extend DES2 key to DES3 key. */
  632. memcpy(newdeskey, att->attrib.pValue, 16);
  633. memcpy(newdeskey + 16, newdeskey, 8);
  634. useNewKey=PR_TRUE;
  635. } else if (key_type == CKK_CDMF) {
  636. crv = sftk_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey);
  637. if (crv != CKR_OK) {
  638. sftk_FreeAttribute(att);
  639. break;
  640. }
  641. useNewKey=PR_TRUE;
  642. }
  643. context->cipherInfo = DES_CreateContext(
  644. useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
  645. (unsigned char*)pMechanism->pParameter,t, isEncrypt);
  646. if (useNewKey)
  647. memset(newdeskey, 0, sizeof newdeskey);
  648. sftk_FreeAttribute(att);
  649. if (context->cipherInfo == NULL) {
  650. crv = CKR_HOST_MEMORY;
  651. break;
  652. }
  653. context->update = (SFTKCipher) (isEncrypt ? DES_Encrypt : DES_Decrypt);
  654. context->destroy = (SFTKDestroy) DES_DestroyContext;
  655. break;
  656. case CKM_SEED_CBC_PAD:
  657. context->doPad = PR_TRUE;
  658. /* fall thru */
  659. case CKM_SEED_CBC:
  660. if (!pMechanism->pParameter ||
  661. pMechanism->ulParameterLen != 16) {
  662. crv = CKR_MECHANISM_PARAM_INVALID;
  663. break;
  664. }
  665. /* fall thru */
  666. case CKM_SEED_ECB:
  667. context->blockSize = 16;
  668. if (key_type != CKK_SEED) {
  669. crv = CKR_KEY_TYPE_INCONSISTENT;
  670. break;
  671. }
  672. att = sftk_FindAttribute(key,CKA_VALUE);
  673. if (att == NULL) {
  674. crv = CKR_KEY_HANDLE_INVALID;
  675. break;
  676. }
  677. context->cipherInfo = SEED_CreateContext(
  678. (unsigned char*)att->attrib.pValue,
  679. (unsigned char*)pMechanism->pParameter,
  680. pMechanism->mechanism == CKM_SEED_ECB ? NSS_SEED : NSS_SEED_CBC,
  681. isEncrypt);
  682. sftk_FreeAttribute(att);
  683. if (context->cipherInfo == NULL) {
  684. crv = CKR_HOST_MEMORY;
  685. break;
  686. }
  687. context->update = (SFTKCipher)(isEncrypt ? SEED_Encrypt : SEED_Decrypt);
  688. context->destroy = (SFTKDestroy) SEED_DestroyContext;
  689. break;
  690. case CKM_CAMELLIA_CBC_PAD:
  691. context->doPad = PR_TRUE;
  692. /* fall thru */
  693. case CKM_CAMELLIA_CBC:
  694. if (!pMechanism->pParameter ||
  695. pMechanism->ulParameterLen != 16) {
  696. crv = CKR_MECHANISM_PARAM_INVALID;
  697. break;
  698. }
  699. /* fall thru */
  700. case CKM_CAMELLIA_ECB:
  701. context->blockSize = 16;
  702. if (key_type != CKK_CAMELLIA) {
  703. crv = CKR_KEY_TYPE_INCONSISTENT;
  704. break;
  705. }
  706. att = sftk_FindAttribute(key,CKA_VALUE);
  707. if (att == NULL) {
  708. crv = CKR_KEY_HANDLE_INVALID;
  709. break;
  710. }
  711. context->cipherInfo = Camellia_CreateContext(
  712. (unsigned char*)att->attrib.pValue,
  713. (unsigned char*)pMechanism->pParameter,
  714. pMechanism->mechanism ==
  715. CKM_CAMELLIA_ECB ? NSS_CAMELLIA : NSS_CAMELLIA_CBC,
  716. isEncrypt, att->attrib.ulValueLen);
  717. sftk_FreeAttribute(att);
  718. if (context->cipherInfo == NULL) {
  719. crv = CKR_HOST_MEMORY;
  720. break;
  721. }
  722. context->update = (SFTKCipher) (isEncrypt ?
  723. Camellia_Encrypt : Camellia_Decrypt);
  724. context->destroy = (SFTKDestroy) Camellia_DestroyContext;
  725. break;
  726. case CKM_AES_CBC_PAD:
  727. context->doPad = PR_TRUE;
  728. /* fall thru */
  729. case CKM_AES_ECB:
  730. case CKM_AES_CBC:
  731. context->blockSize = 16;
  732. if (key_type != CKK_AES) {
  733. crv = CKR_KEY_TYPE_INCONSISTENT;
  734. break;
  735. }
  736. att = sftk_FindAttribute(key,CKA_VALUE);
  737. if (att == NULL) {
  738. crv = CKR_KEY_HANDLE_INVALID;
  739. break;
  740. }
  741. context->cipherInfo = AES_CreateContext(
  742. (unsigned char*)att->attrib.pValue,
  743. (unsigned char*)pMechanism->pParameter,
  744. pMechanism->mechanism == CKM_AES_ECB ? NSS_AES : NSS_AES_CBC,
  745. isEncrypt, att->attrib.ulValueLen, 16);
  746. sftk_FreeAttribute(att);
  747. if (context->cipherInfo == NULL) {
  748. crv = CKR_HOST_MEMORY;
  749. break;
  750. }
  751. context->update = (SFTKCipher) (isEncrypt ? AES_Encrypt : AES_Decrypt);
  752. context->destroy = (SFTKDestroy) AES_DestroyContext;
  753. break;
  754. case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
  755. context->doPad = PR_TRUE;
  756. /* fall thru */
  757. case CKM_NETSCAPE_AES_KEY_WRAP:
  758. context->multi = PR_FALSE;
  759. context->blockSize = 8;
  760. if (key_type != CKK_AES) {
  761. crv = CKR_KEY_TYPE_INCONSISTENT;
  762. break;
  763. }
  764. att = sftk_FindAttribute(key,CKA_VALUE);
  765. if (att == NULL) {
  766. crv = CKR_KEY_HANDLE_INVALID;
  767. break;
  768. }
  769. context->cipherInfo = AESKeyWrap_CreateContext(
  770. (unsigned char*)att->attrib.pValue,
  771. (unsigned char*)pMechanism->pParameter,
  772. isEncrypt, att->attrib.ulValueLen);
  773. sftk_FreeAttribute(att);
  774. if (context->cipherInfo == NULL) {
  775. crv = CKR_HOST_MEMORY;
  776. break;
  777. }
  778. context->update = (SFTKCipher) (isEncrypt ? AESKeyWrap_Encrypt
  779. : AESKeyWrap_Decrypt);
  780. context->destroy = (SFTKDestroy) AESKeyWrap_DestroyContext;
  781. break;
  782. default:
  783. crv = CKR_MECHANISM_INVALID;
  784. break;
  785. }
  786. if (crv != CKR_OK) {
  787. sftk_FreeContext(context);
  788. sftk_FreeSession(session);
  789. return crv;
  790. }
  791. sftk_SetContextByType(session, contextType, context);
  792. sftk_FreeSession(session);
  793. return CKR_OK;
  794. }
  795. /* NSC_EncryptInit initializes an encryption operation. */
  796. CK_RV NSC_EncryptInit(CK_SESSION_HANDLE hSession,
  797. CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
  798. {
  799. CHECK_FORK();
  800. return sftk_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT, CKA_ENCRYPT,
  801. SFTK_ENCRYPT, PR_TRUE);
  802. }
  803. /* NSC_EncryptUpdate continues a multiple-part encryption operation. */
  804. CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
  805. CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
  806. CK_ULONG_PTR pulEncryptedPartLen)
  807. {
  808. SFTKSessionContext *context;
  809. unsigned int outlen,i;
  810. unsigned int padoutlen = 0;
  811. unsigned int maxout = *pulEncryptedPartLen;
  812. CK_RV crv;
  813. SECStatus rv;
  814. CHECK_FORK();
  815. /* make sure we're legal */
  816. crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,NULL);
  817. if (crv != CKR_OK) return crv;
  818. if (!pEncryptedPart) {
  819. if (context->doPad) {
  820. CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength;
  821. CK_ULONG blocksToSend = totalDataAvailable/context->blockSize;
  822. *pulEncryptedPartLen = blocksToSend * context->blockSize;
  823. return CKR_OK;
  824. }
  825. *pulEncryptedPartLen = ulPartLen;
  826. return CKR_OK;
  827. }
  828. /* do padding */
  829. if (context->doPad) {
  830. /* deal with previous buffered data */
  831. if (context->padDataLength != 0) {
  832. /* fill in the padded to a full block size */
  833. for (i=context->padDataLength;
  834. (ulPartLen != 0) && i < context->blockSize; i++) {
  835. context->padBuf[i] = *pPart++;
  836. ulPartLen--;
  837. context->padDataLength++;
  838. }
  839. /* not enough data to encrypt yet? then return */
  840. if (context->padDataLength != context->blockSize) {
  841. *pulEncryptedPartLen = 0;
  842. return CKR_OK;
  843. }
  844. /* encrypt the current padded data */
  845. rv = (*context->update)(context->cipherInfo, pEncryptedPart,
  846. &padoutlen, context->blockSize, context->padBuf,
  847. context->blockSize);
  848. if (rv != SECSuccess) {
  849. return sftk_MapCryptError(PORT_GetError());
  850. }
  851. pEncryptedPart += padoutlen;
  852. maxout -= padoutlen;
  853. }
  854. /* save the residual */
  855. context->padDataLength = ulPartLen % context->blockSize;
  856. if (context->padDataLength) {
  857. PORT_Memcpy(context->padBuf,
  858. &pPart[ulPartLen-context->padDataLength],
  859. context->padDataLength);
  860. ulPartLen -= context->padDataLength;
  861. }
  862. /* if we've exhausted our new buffer, we're done */
  863. if (ulPartLen == 0) {
  864. *pulEncryptedPartLen = padoutlen;
  865. return CKR_OK;
  866. }
  867. }
  868. /* do it: NOTE: this assumes buf size in is >= buf size out! */
  869. rv = (*context->update)(context->cipherInfo,pEncryptedPart,
  870. &outlen, maxout, pPart, ulPartLen);
  871. *pulEncryptedPartLen = (CK_ULONG) (outlen + padoutlen);
  872. return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
  873. }
  874. /* NSC_EncryptFinal finishes a multiple-part encryption operation. */
  875. CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
  876. CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
  877. {
  878. SFTKSession *session;
  879. SFTKSessionContext *context;
  880. unsigned int outlen,i;
  881. unsigned int maxout = *pulLastEncryptedPartLen;
  882. CK_RV crv;
  883. SECStatus rv = SECSuccess;
  884. PRBool contextFinished = PR_TRUE;
  885. CHECK_FORK();
  886. /* make sure we're legal */
  887. crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,&session);
  888. if (crv != CKR_OK) return crv;
  889. *pulLastEncryptedPartLen = 0;
  890. if (!pLastEncryptedPart) {
  891. /* caller is checking the amount of remaining data */
  892. if (context->blockSize > 0 && context->doPad) {
  893. *pulLastEncryptedPartLen = context->blockSize;
  894. contextFinished = PR_FALSE; /* still have padding to go */
  895. }
  896. goto finish;
  897. }
  898. /* do padding */
  899. if (context->doPad) {
  900. unsigned char padbyte = (unsigned char)
  901. (context->blockSize - context->padDataLength);
  902. /* fill out rest of pad buffer with pad magic*/
  903. for (i=context->padDataLength; i < context->blockSize; i++) {
  904. context->padBuf[i] = padbyte;
  905. }
  906. rv = (*context->update)(context->cipherInfo,pLastEncryptedPart,
  907. &outlen, maxout, context->padBuf, context->blockSize);
  908. if (rv == SECSuccess) *pulLastEncryptedPartLen = (CK_ULONG) outlen;
  909. }
  910. finish:
  911. if (contextFinished)
  912. sftk_TerminateOp( session, SFTK_ENCRYPT, context );
  913. sftk_FreeSession(session);
  914. return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
  915. }
  916. /* NSC_Encrypt encrypts single-part data. */
  917. CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
  918. CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
  919. CK_ULONG_PTR pulEncryptedDataLen)
  920. {
  921. SFTKSession *session;
  922. SFTKSessionContext *context;
  923. unsigned int outlen;
  924. unsigned int maxoutlen = *pulEncryptedDataLen;
  925. CK_RV crv;
  926. CK_RV crv2;
  927. SECStatus rv = SECSuccess;
  928. SECItem pText;
  929. pText.type = siBuffer;
  930. pText.data = pData;
  931. pText.len = ulDataLen;
  932. CHECK_FORK();
  933. /* make sure we're legal */
  934. crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_FALSE,&session);
  935. if (crv != CKR_OK) return crv;
  936. if (!pEncryptedData) {
  937. *pulEncryptedDataLen = context->multi ?
  938. ulDataLen + 2 * context->blockSize : context->maxLen;
  939. goto finish;
  940. }
  941. if (context->doPad) {
  942. if (context->multi) {
  943. CK_ULONG finalLen;
  944. /* padding is fairly complicated, have the update and final
  945. * code deal with it */
  946. sftk_FreeSession(session);
  947. crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData,
  948. pulEncryptedDataLen);
  949. if (crv != CKR_OK)
  950. *pulEncryptedDataLen = 0;
  951. maxoutlen -= *pulEncryptedDataLen;
  952. pEncryptedData += *pulEncryptedDataLen;
  953. finalLen = maxoutlen;
  954. crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen);
  955. if (crv2 == CKR_OK)
  956. *pulEncryptedDataLen += finalLen;
  957. return crv == CKR_OK ? crv2 : crv;
  958. }
  959. /* doPad without multi means that padding must be done on the first
  960. ** and only update. There will be no final.
  961. */
  962. PORT_Assert(context->blockSize > 1);
  963. if (context->blockSize > 1) {
  964. CK_ULONG remainder = ulDataLen % context->blockSize;
  965. CK_ULONG padding = context->blockSize - remainder;
  966. pText.len += padding;
  967. pText.data = PORT_ZAlloc(pText.len);
  968. if (pText.data) {
  969. memcpy(pText.data, pData, ulDataLen);
  970. memset(pText.data + ulDataLen, padding, padding);
  971. } else {
  972. crv = CKR_HOST_MEMORY;
  973. goto fail;
  974. }
  975. }
  976. }
  977. /* do it: NOTE: this assumes buf size is big enough. */
  978. rv = (*context->update)(context->cipherInfo, pEncryptedData,
  979. &outlen, maxoutlen, pText.data, pText.len);
  980. crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
  981. *pulEncryptedDataLen = (CK_ULONG) outlen;
  982. if (pText.data != pData)
  983. PORT_ZFree(pText.data, pText.len);
  984. fail:
  985. sftk_TerminateOp( session, SFTK_ENCRYPT, context );
  986. finish:
  987. sftk_FreeSession(session);
  988. return crv;
  989. }
  990. /*
  991. ************** Crypto Functions: Decrypt ************************
  992. */
  993. /* NSC_DecryptInit initializes a decryption operation. */
  994. CK_RV NSC_DecryptInit( CK_SESSION_HANDLE hSession,
  995. CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
  996. {
  997. CHECK_FORK();
  998. return sftk_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT, CKA_DECRYPT,
  999. SFTK_DECRYPT, PR_FALSE);
  1000. }
  1001. /* NSC_DecryptUpdate continues a multiple-part decryption operation. */
  1002. CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
  1003. CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
  1004. CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
  1005. {
  1006. SFTKSessionContext *context;
  1007. unsigned int padoutlen = 0;
  1008. unsigned int outlen;
  1009. unsigned int maxout = *pulPartLen;
  1010. CK_RV crv;
  1011. SECStatus rv;
  1012. CHECK_FORK();
  1013. /* make sure we're legal */
  1014. crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL);
  1015. if (crv != CKR_OK) return crv;
  1016. /* this can only happen on an NSS programming error */
  1017. PORT_Assert((context->padDataLength == 0)
  1018. || context->padDataLength == context->blockSize);
  1019. if (!pPart) {
  1020. if (context->doPad) {
  1021. /* we can check the data length here because if we are padding,
  1022. * then we must be using a block cipher. In the non-padding case
  1023. * the error will be returned by the underlying decryption
  1024. * function when do do the actual decrypt. We need to do the
  1025. * check here to avoid returning a negative length to the caller.
  1026. */
  1027. if ((ulEncryptedPartLen == 0) ||
  1028. (ulEncryptedPartLen % context->blockSize) != 0) {
  1029. return CKR_ENCRYPTED_DATA_LEN_RANGE;
  1030. }
  1031. *pulPartLen =
  1032. ulEncryptedPartLen + context->padDataLength - context->blockSize;
  1033. return CKR_OK;
  1034. }
  1035. /* for stream ciphers there is are no constraints on ulEncryptedPartLen.
  1036. * for block ciphers, it must be a multiple of blockSize. The error is
  1037. * detected when this function is called again do decrypt the output.
  1038. */
  1039. *pulPartLen = ulEncryptedPartLen;
  1040. return CKR_OK;
  1041. }
  1042. if (context->doPad) {
  1043. /* first decrypt our saved buffer */
  1044. if (context->padDataLength != 0) {
  1045. rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
  1046. maxout, context->padBuf, context->blockSize);
  1047. if (rv != SECSuccess) return sftk_MapDecryptError(PORT_GetError());
  1048. pPart += padoutlen;
  1049. maxout -= padoutlen;
  1050. }
  1051. /* now save the final block for the next decrypt or the final */
  1052. PORT_Memcpy(context->padBuf,&pEncryptedPart[ulEncryptedPartLen -
  1053. context->blockSize], context->blockSize);
  1054. context->padDataLength = context->blockSize;
  1055. ulEncryptedPartLen -= context->padDataLength;
  1056. }
  1057. /* do it: NOTE: this assumes buf size in is >= buf size out! */
  1058. rv = (*context->update)(context->cipherInfo,pPart, &outlen,
  1059. maxout, pEncryptedPart, ulEncryptedPartLen);
  1060. *pulPartLen = (CK_ULONG) (outlen + padoutlen);
  1061. return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
  1062. }
  1063. /* NSC_DecryptFinal finishes a multiple-part decryption operation. */
  1064. CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
  1065. CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
  1066. {
  1067. SFTKSession *session;
  1068. SFTKSessionContext *context;
  1069. unsigned int outlen;
  1070. unsigned int maxout = *pulLastPartLen;
  1071. CK_RV crv;
  1072. SECStatus rv = SECSuccess;
  1073. CHECK_FORK();
  1074. /* make sure we're legal */
  1075. crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,&session);
  1076. if (crv != CKR_OK) return crv;
  1077. *pulLastPartLen = 0;
  1078. if (!pLastPart) {
  1079. /* caller is checking the amount of remaining data */
  1080. if (context->padDataLength > 0) {
  1081. *pulLastPartLen = context->padDataLength;
  1082. }
  1083. rv = SECSuccess;
  1084. goto finish;
  1085. }
  1086. if (context->doPad) {
  1087. /* decrypt our saved buffer */
  1088. if (context->padDataLength != 0) {
  1089. /* this assumes that pLastPart is big enough to hold the *whole*
  1090. * buffer!!! */
  1091. rv = (*context->update)(context->cipherInfo, pLastPart, &outlen,
  1092. maxout, context->padBuf, context->blockSize);
  1093. if (rv == SECSuccess) {
  1094. unsigned int padSize =
  1095. (unsigned int) pLastPart[context->blockSize-1];
  1096. if ((padSize > context->blockSize) || (padSize == 0)) {
  1097. rv = SECFailure;
  1098. } else {
  1099. *pulLastPartLen = outlen - padSize;
  1100. }
  1101. }
  1102. }
  1103. }
  1104. sftk_TerminateOp( session, SFTK_DECRYPT, context );
  1105. finish:
  1106. sftk_FreeSession(session);
  1107. return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
  1108. }
  1109. /* NSC_Decrypt decrypts encrypted data in a single part. */
  1110. CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession,
  1111. CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,
  1112. CK_ULONG_PTR pulDataLen)
  1113. {
  1114. SFTKSession *session;
  1115. SFTKSessionContext *context;
  1116. unsigned int outlen;
  1117. unsigned int maxoutlen = *pulDataLen;
  1118. CK_RV crv;
  1119. CK_RV crv2;
  1120. SECStatus rv = SECSuccess;
  1121. CHECK_FORK();
  1122. /* make sure we're legal */
  1123. crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_FALSE,&session);
  1124. if (crv != CKR_OK) return crv;
  1125. if (!pData) {
  1126. *pulDataLen = ulEncryptedDataLen + context->blockSize;
  1127. goto finish;
  1128. }
  1129. if (context->doPad && context->multi) {
  1130. CK_ULONG finalLen;
  1131. /* padding is fairly complicated, have the update and final
  1132. * code deal with it */
  1133. sftk_FreeSession(session);
  1134. crv = NSC_DecryptUpdate(hSession,pEncryptedData,ulEncryptedDataLen,
  1135. pData, pulDataLen);
  1136. if (crv != CKR_OK)
  1137. *pulDataLen = 0;
  1138. maxoutlen -= *pulDataLen;
  1139. pData += *pulDataLen;
  1140. finalLen = maxoutlen;
  1141. crv2 = NSC_DecryptFinal(hSession, pData, &finalLen);
  1142. if (crv2 == CKR_OK)
  1143. *pulDataLen += finalLen;
  1144. return crv == CKR_OK ? crv2 : crv;
  1145. }
  1146. rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
  1147. pEncryptedData, ulEncryptedDataLen);
  1148. /* XXX need to do MUCH better error mapping than this. */
  1149. crv = (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
  1150. if (rv == SECSuccess && context->doPad) {
  1151. CK_ULONG padding = pData[outlen - 1];
  1152. if (padding > context->blockSize || !padding) {
  1153. crv = CKR_ENCRYPTED_DATA_INVALID;
  1154. } else
  1155. outlen -= padding;
  1156. }
  1157. *pulDataLen = (CK_ULONG) outlen;
  1158. sftk_TerminateOp( session, SFTK_DECRYPT, context );
  1159. finish:
  1160. sftk_FreeSession(session);
  1161. return crv;
  1162. }
  1163. /*
  1164. ************** Crypto Functions: Digest (HASH) ************************
  1165. */
  1166. /* NSC_DigestInit initializes a message-digesting operation. */
  1167. CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession,
  1168. CK_MECHANISM_PTR pMechanism)
  1169. {
  1170. SFTKSession *session;
  1171. SFTKSessionContext *context;
  1172. CK_RV crv = CKR_OK;
  1173. CHECK_FORK();
  1174. session = sftk_SessionFromHandle(hSession);
  1175. if (session == NULL)
  1176. return CKR_SESSION_HANDLE_INVALID;
  1177. crv = sftk_InitGeneric(session,&context,SFTK_HASH,NULL,0,NULL, 0, 0);
  1178. if (crv != CKR_OK) {
  1179. sftk_FreeSession(session);
  1180. return crv;
  1181. }
  1182. #define INIT_MECH(mech,mmm) \
  1183. case mech: { \
  1184. mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \
  1185. context->cipherInfo = (void *)mmm ## _ctx; \
  1186. context->cipherInfoLen = mmm ## _FlattenSize(mmm ## _ctx); \
  1187. context->currentMech = mech; \
  1188. context->hashUpdate = (SFTKHash) mmm ## _Update; \
  1189. context->end = (SFTKEnd) mmm ## _End; \
  1190. context->destroy = (SFTKDestroy) mmm ## _DestroyContext; \
  1191. context->maxLen = mmm ## _LENGTH; \
  1192. if (mmm ## _ctx) \
  1193. mmm ## _Begin(mmm ## _ctx); \
  1194. else \
  1195. crv = CKR_HOST_MEMORY; \
  1196. break; \
  1197. }
  1198. switch(pMechanism->mechanism) {
  1199. INIT_MECH(CKM_MD2, MD2)
  1200. INIT_MECH(CKM_MD5, MD5)
  1201. INIT_MECH(CKM_SHA_1, SHA1)
  1202. INIT_MECH(CKM_SHA224, SHA224)
  1203. INIT_MECH(CKM_SHA256, SHA256)
  1204. INIT_MECH(CKM_SHA384, SHA384)
  1205. INIT_MECH(CKM_SHA512, SHA512)
  1206. default:
  1207. crv = CKR_MECHANISM_INVALID;
  1208. break;
  1209. }
  1210. if (crv != CKR_OK) {
  1211. sftk_FreeContext(context);
  1212. sftk_FreeSession(session);
  1213. return crv;
  1214. }
  1215. sftk_SetContextByType(session, SFTK_HASH, context);
  1216. sftk_FreeSession(session);
  1217. return CKR_OK;
  1218. }
  1219. /* NSC_Digest digests data in a single part. */
  1220. CK_RV NSC_Digest(CK_SESSION_HANDLE hSession,
  1221. CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest,
  1222. CK_ULONG_PTR pulDigestLen)
  1223. {
  1224. SFTKSession *session;
  1225. SFTKSessionContext *context;
  1226. unsigned int digestLen;
  1227. unsigned int maxout = *pulDigestLen;
  1228. CK_RV crv;
  1229. CHECK_FORK();
  1230. /* make sure we're legal */
  1231. crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_FALSE,&session);
  1232. if (crv != CKR_OK) return crv;
  1233. if (pDigest == NULL) {
  1234. *pulDigestLen = context->maxLen;
  1235. goto finish;
  1236. }
  1237. /* do it: */
  1238. (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen);
  1239. /* NOTE: this assumes buf size is bigenough for the algorithm */
  1240. (*context->end)(context->cipherInfo, pDigest, &digestLen,maxout);
  1241. *pulDigestLen = digestLen;
  1242. sftk_TerminateOp( session, SFTK_HASH, context );
  1243. finish:
  1244. sftk_FreeSession(session);
  1245. return CKR_OK;
  1246. }
  1247. /* NSC_DigestUpdate continues a multiple-part message-digesting operation. */
  1248. CK_RV NSC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
  1249. CK_ULONG ulPartLen)
  1250. {
  1251. SFTKSessionContext *context;
  1252. CK_RV crv;
  1253. CHECK_FORK();
  1254. /* make sure we're legal */
  1255. crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_TRUE,NULL);
  1256. if (crv != CKR_OK) return crv;
  1257. /* do it: */
  1258. (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen);
  1259. return CKR_OK;
  1260. }
  1261. /* NSC_DigestFinal finishes a multiple-part message-digesting operation. */
  1262. CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
  1263. CK_ULONG_PTR pulDigestLen)
  1264. {
  1265. SFTKSession *session;
  1266. SFTKSessionContext *context;
  1267. unsigned int maxout = *pulDigestLen;
  1268. unsigned int digestLen;
  1269. CK_RV crv;
  1270. CHECK_FORK();
  1271. /* make sure we're legal */
  1272. crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
  1273. if (crv != CKR_OK) return crv;
  1274. if (pDigest != NULL) {
  1275. (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
  1276. *pulDigestLen = digestLen;
  1277. sftk_TerminateOp( session, SFTK_HASH, context );
  1278. } else {
  1279. *pulDigestLen = context->maxLen;
  1280. }
  1281. sftk_FreeSession(session);
  1282. return CKR_OK;
  1283. }
  1284. /*
  1285. * these helper functions are used by Generic Macing and Signing functions
  1286. * that use hashes as part of their operations.
  1287. */
  1288. #define DOSUB(mmm) \
  1289. static CK_RV \
  1290. sftk_doSub ## mmm(SFTKSessionContext *context) { \
  1291. mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \
  1292. context->hashInfo = (void *) mmm ## _ctx; \
  1293. context->hashUpdate = (SFTKHash) mmm ## _Update; \
  1294. context->end = (SFTKEnd) mmm ## _End; \
  1295. context->hashdestroy = (SFTKDestroy) mmm ## _DestroyContext; \
  1296. if (!context->hashInfo) { \
  1297. return CKR_HOST_MEMORY; \
  1298. } \
  1299. mmm ## _Begin( mmm ## _ctx ); \
  1300. return CKR_OK; \
  1301. }
  1302. DOSUB(MD2)
  1303. DOSUB(MD5)
  1304. DOSUB(SHA1)
  1305. DOSUB(SHA224)
  1306. DOSUB(SHA256)
  1307. DOSUB(SHA384)
  1308. DOSUB(SHA512)
  1309. /*
  1310. * HMAC General copies only a portion of the result. This update routine likes
  1311. * the final HMAC output with the signature.
  1312. */
  1313. static SECStatus
  1314. sftk_HMACCopy(CK_ULONG *copyLen,unsigned char *sig,unsigned int *sigLen,
  1315. unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
  1316. {
  1317. if (maxLen < *copyLen) return SECFailure;
  1318. PORT_Memcpy(sig,hash,*copyLen);
  1319. *sigLen = *copyLen;
  1320. return SECSuccess;
  1321. }
  1322. /* Verify is just a compare for HMAC */
  1323. static SECStatus
  1324. sftk_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen,
  1325. unsigned char *hash, unsigned int hashLen)
  1326. {
  1327. return (PORT_Memcmp(sig,hash,*copyLen) == 0) ? SECSuccess : SECFailure ;
  1328. }
  1329. /*
  1330. * common HMAC initalization routine
  1331. */
  1332. static CK_RV
  1333. sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType hash,
  1334. SFTKObject *key, CK_ULONG mac_size)
  1335. {
  1336. SFTKAttribute *keyval;
  1337. HMACContext *HMACcontext;
  1338. CK_ULONG *intpointer;
  1339. const SECHashObject *hashObj = HASH_GetRawHashObject(hash);
  1340. PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);
  1341. /* required by FIPS 198 Section 4 */
  1342. if (isFIPS && (mac_size < 4 || mac_size < hashObj->length/2)) {
  1343. return CKR_BUFFER_TOO_SMALL;
  1344. }
  1345. keyval = sftk_FindAttribute(key,CKA_VALUE);
  1346. if (keyval == NULL) return CKR_KEY_SIZE_RANGE;
  1347. HMACcontext = HMAC_Create(hashObj,
  1348. (const unsigned char*)keyval->attrib.pValue,
  1349. keyval->attrib.ulValueLen, isFIPS);
  1350. context->hashInfo = HMACcontext;
  1351. context->multi = PR_TRUE;
  1352. sftk_FreeAttribute(keyval);
  1353. if (context->hashInfo == NULL) {
  1354. if (PORT_GetError() == SEC_ERROR_INVALID_ARGS) {
  1355. return CKR_KEY_SIZE_RANGE;
  1356. }
  1357. return CKR_HOST_MEMORY;
  1358. }
  1359. context->hashUpdate = (SFTKHash) HMAC_Update;
  1360. context->end = (SFTKEnd) HMAC_Finish;
  1361. context->hashdestroy = (SFTKDestroy) HMAC_Destroy;
  1362. intpointer = (CK_ULONG *) PORT_Alloc(sizeof(CK_ULONG));
  1363. if (intpointer == NULL) {
  1364. return CKR_HOST_MEMORY;
  1365. }
  1366. *intpointer = mac_size;
  1367. context->cipherInfo = (void *) intpointer;
  1368. context->destroy = (SFTKDestroy) sftk_Space;
  1369. context->update = (SFTKCipher) sftk_HMACCopy;
  1370. context->verify = (SFTKVerify) sftk_HMACCmp;
  1371. context->maxLen = hashObj->length;
  1372. HMAC_Begin(HMACcontext);
  1373. return CKR_OK;
  1374. }
  1375. /*
  1376. * SSL Macing support. SSL Macs are inited, then update with the base
  1377. * hashing algorithm, then finalized in sign and verify
  1378. */
  1379. /*
  1380. * FROM SSL:
  1381. * 60 bytes is 3 times the maximum length MAC size that is supported.
  1382. * We probably should have one copy of this table. We still need this table
  1383. * in ssl to 'sign' the handshake hashes.
  1384. */
  1385. static unsigned char ssl_pad_1 [60] = {
  1386. 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  1387. 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  1388. 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  1389. 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  1390. 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  1391. 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  1392. 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  1393. 0x36, 0x36, 0x36, 0x36
  1394. };
  1395. static unsigned char ssl_pad_2 [60] = {
  1396. 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
  1397. 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
  1398. 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
  1399. 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
  1400. 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
  1401. 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
  1402. 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
  1403. 0x5c, 0x5c, 0x5c, 0x5c
  1404. };
  1405. static SECStatus
  1406. sftk_SSLMACSign(SFTKSSLMACInfo *info,unsigned char *sig,unsigned int *sigLen,
  1407. unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
  1408. {
  1409. unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH];
  1410. unsigned int out;
  1411. info->begin(info->hashContext);
  1412. info->update(info->hashContext,info->key,info->keySize);
  1413. info->update(info->hashContext,ssl_pad_2,info->padSize);
  1414. info->update(info->hashContext,hash,hashLen);
  1415. info->end(info->hashContext,tmpBuf,&out,SFTK_MAX_MAC_LENGTH);
  1416. PORT_Memcpy(sig,tmpBuf,info->macSize);
  1417. *sigLen = info->macSize;
  1418. return SECSuccess;
  1419. }
  1420. static SECStatus
  1421. sftk_SSLMACVerify(SFTKSSLMACInfo *info,unsigned char *sig,unsigned int sigLen,
  1422. unsigned char *hash, unsigned int hashLen)
  1423. {
  1424. unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH];
  1425. unsigned int out;
  1426. info->begin(info->hashContext);
  1427. info->update(info->hashContext,info->key,info->keySize);
  1428. info->update(info->hashContext,ssl_pad_2,info->padSize);
  1429. info->update(info->hashContext,hash,hashLen);
  1430. info->end(info->hashContext,tmpBuf,&out,SFTK_MAX_MAC_LENGTH);
  1431. return (PORT_Memcmp(sig,tmpBuf,info->macSize) == 0) ?
  1432. SECSuccess : SECFailure;
  1433. }
  1434. /*
  1435. * common HMAC initalization routine
  1436. */
  1437. static CK_RV
  1438. sftk_doSSLMACInit(SFTKSessionContext *context,SECOidTag oid,
  1439. SFTKObject *key, CK_ULONG mac_size)
  1440. {
  1441. SFTKAttribute *keyval;
  1442. SFTKBegin begin;
  1443. int padSize;
  1444. SFTKSSLMACInfo *sslmacinfo;
  1445. CK_RV crv = CKR_MECHANISM_INVALID;
  1446. if (oid == SEC_OID_SHA1) {
  1447. crv = sftk_doSubSHA1(context);
  1448. if (crv != CKR_OK) return crv;
  1449. begin = (SFTKBegin) SHA1_Begin;
  1450. padSize = 40;
  1451. } else {
  1452. crv = sftk_doSubMD5(context);
  1453. if (crv != CKR_OK) return crv;
  1454. begin = (SFTKBegin) MD5_Begin;
  1455. padSize = 48;
  1456. }
  1457. context->multi = PR_TRUE;
  1458. keyval = sftk_FindAttribute(key,CKA_VALUE);
  1459. if (keyval == NULL) return CKR_KEY_SIZE_RANGE;
  1460. context->hashUpdate(context->hashInfo,keyval->attrib.pValue,
  1461. keyval->attrib.ulValueLen);
  1462. context->hashUpdate(context->hashInfo,ssl_pad_1,padSize);
  1463. sslmacinfo = (SFTKSSLMACInfo *) PORT_Alloc(sizeof(SFTKSSLMACInfo));
  1464. if (sslmacinfo == NULL) {
  1465. sftk_FreeAttribute(keyval);
  1466. return CKR_HOST_MEMORY;
  1467. }
  1468. sslmacinfo->macSize = mac_size;
  1469. sslmacinfo->hashContext = context->hashInfo;
  1470. PORT_Memcpy(sslmacinfo->key,keyval->attrib.pValue,
  1471. keyval->attrib.ulValueLen);
  1472. sslmacinfo->keySize = keyval->attrib.ulValueLen;
  1473. sslmacinfo->begin = begin;
  1474. sslmacinfo->end = context->end;
  1475. sslmacinfo->update = context->hashUpdate;
  1476. sslmacinfo->padSize = padSize;
  1477. sftk_FreeAttribute(keyval);
  1478. context->cipherInfo = (void *) sslmacinfo;
  1479. context->destroy = (SFTKDestroy) sftk_Space;
  1480. context->update = (SFTKCipher) sftk_SSLMACSign;
  1481. context->verify = (SFTKVerify) sftk_SSLMACVerify;
  1482. context->maxLen = mac_size;
  1483. return CKR_OK;
  1484. }
  1485. /*
  1486. ************** Crypto Functions: Sign ************************
  1487. */
  1488. /**
  1489. * Check if We're using CBCMacing and initialize the session context if we are.
  1490. * @param contextType SFTK_SIGN or SFTK_VERIFY
  1491. * @param keyUsage check whether key allows this usage
  1492. */
  1493. static CK_RV
  1494. sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
  1495. CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage,
  1496. SFTKContextType contextType)
  1497. {
  1498. CK_MECHANISM cbc_mechanism;
  1499. CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE;
  1500. CK_RC2_CBC_PARAMS rc2_params;
  1501. #if NSS_SOFTOKEN_DOES_RC5
  1502. CK_RC5_CBC_PARAMS rc5_params;
  1503. CK_RC5_MAC_GENERAL_PARAMS *rc5_mac;
  1504. #endif
  1505. unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE];
  1506. SFTKSessionContext *context;
  1507. CK_RV crv;
  1508. unsigned int blockSize;
  1509. switch (pMechanism->mechanism) {
  1510. case CKM_RC2_MAC_GENERAL:
  1511. mac_bytes =
  1512. ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
  1513. /* fall through */
  1514. case CKM_RC2_MAC:
  1515. /* this works because ulEffectiveBits is in the same place in both the
  1516. * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */
  1517. rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *)
  1518. pMechanism->pParameter)->ulEffectiveBits;
  1519. PORT_Memset(rc2_params.iv,0,sizeof(rc2_params.iv));
  1520. cbc_mechanism.mechanism = CKM_RC2_CBC;
  1521. cbc_mechanism.pParameter = &rc2_params;
  1522. cbc_mechanism.ulParameterLen = sizeof(rc2_params);
  1523. blockSize = 8;
  1524. break;
  1525. #if NSS_SOFTOKEN_DOES_RC5
  1526. case CKM_RC5_MAC_GENERAL:
  1527. mac_bytes =
  1528. ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
  1529. /* fall through */
  1530. case CKM_RC5_MAC:
  1531. /* this works because ulEffectiveBits is in the same place in both the
  1532. * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */
  1533. rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter;
  1534. rc5_params.ulWordsize = rc5_mac->ulWordsize;
  1535. rc5_params.ulRounds = rc5_mac->ulRounds;
  1536. rc5_params.pIv = ivBlock;
  1537. if( (blockSize = rc5_mac->ulWordsize*2) > SFTK_MAX_BLOCK_SIZE )
  1538. return CKR_MECHANISM_PARAM_INVALID;
  1539. rc5_params.ulIvLen = blockSize;
  1540. PORT_Memset(ivBlock,0,blockSize);
  1541. cbc_mechanism.mechanism = CKM_RC5_CBC;
  1542. cbc_mechanism.pParameter = &rc5_params;
  1543. cbc_mechanism.ulParameterLen = sizeof(rc5_params);
  1544. break;
  1545. #endif
  1546. /* add cast and idea later */
  1547. case CKM_DES_MAC_GENERAL:
  1548. mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
  1549. /* fall through */
  1550. case CKM_DES_MAC:
  1551. blockSize = 8;
  1552. PORT_Memset(ivBlock,0,blockSize);
  1553. cbc_mechanism.mechanism = CKM_DES_CBC;
  1554. cbc_mechanism.pParameter = &ivBlock;
  1555. cbc_mechanism.ulParameterLen = blockSize;
  1556. break;
  1557. case CKM_DES3_MAC_GENERAL:
  1558. mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
  1559. /* fall through */
  1560. case CKM_DES3_MAC:
  1561. blockSize = 8;
  1562. PORT_Memset(ivBlock,0,blockSize);
  1563. cbc_mechanism.mechanism = CKM_DES3_CBC;
  1564. cbc_mechanism.pParameter = &ivBlock;
  1565. cbc_mechanism.ulParameterLen = blockSize;
  1566. break;
  1567. case CKM_CDMF_MAC_GENERAL:
  1568. mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
  1569. /* fall through */
  1570. case CKM_CDMF_MAC:
  1571. blockSize = 8;
  1572. PORT_Memset(ivBlock,0,blockSize);
  1573. cbc_mechanism.mechanism = CKM_CDMF_CBC;
  1574. cbc_mechanism.pParameter = &ivBlock;
  1575. cbc_mechanism.ulParameterLen = blockSize;
  1576. break;
  1577. case CKM_SEED_MAC_GENERAL:
  1578. mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
  1579. /* fall through */
  1580. case CKM_SEED_MAC:
  1581. blockSize = 16;
  1582. PORT_Memset(ivBlock,0,blockSize);
  1583. cbc_mechanism.mechanism = CKM_SEED_CBC;
  1584. cbc_mechanism.pParameter = &ivBlock;
  1585. cbc_mechanism.ulParameterLen = blockSize;
  1586. break;
  1587. case CKM_CAMELLIA_MAC_GENERAL:
  1588. mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
  1589. /* fall through */
  1590. case CKM_CAMELLIA_MAC:
  1591. blockSize = 16;
  1592. PORT_Memset(ivBlock,0,blockSize);
  1593. cbc_mechanism.mechanism = CKM_CAMELLIA_CBC;
  1594. cbc_mechanism.pParameter = &ivBlock;
  1595. cbc_mechanism.ulParameterLen = blockSize;
  1596. break;
  1597. case CKM_AES_MAC_GENERAL:
  1598. mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
  1599. /* fall through */
  1600. case CKM_AES_MAC:
  1601. blockSize = 16;
  1602. PORT_Memset(ivBlock,0,blockSize);
  1603. cbc_mechanism.mechanism = CKM_AES_CBC;
  1604. cbc_mechanism.pParameter = &ivBlock;
  1605. cbc_mechanism.ulParameterLen = blockSize;
  1606. break;
  1607. default:
  1608. return CKR_FUNCTION_NOT_SUPPORTED;
  1609. }
  1610. /* if MAC size is externally supplied, it should be checked.
  1611. */
  1612. if (mac_bytes == SFTK_INVALID_MAC_SIZE)
  1613. mac_bytes = blockSize >> 1;
  1614. else {
  1615. if( mac_bytes > blockSize )
  1616. return CKR_MECHANISM_PARAM_INVALID;
  1617. }
  1618. crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey,
  1619. CKA_ENCRYPT, /* CBC mech is able to ENCRYPT, not SIGN/VERIFY */
  1620. keyUsage, contextType, PR_TRUE );
  1621. if (crv != CKR_OK) return crv;
  1622. crv = sftk_GetContext(hSession,&context,contextType,PR_TRUE,NULL);
  1623. /* this shouldn't happen! */
  1624. PORT_Assert(crv == CKR_OK);
  1625. if (crv != CKR_OK) return crv;
  1626. context->blockSize = blockSize;
  1627. context->macSize = mac_bytes;
  1628. return CKR_OK;
  1629. }
  1630. /*
  1631. * encode RSA PKCS #1 Signature data before signing...
  1632. */
  1633. static SECStatus
  1634. sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen,
  1635. unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
  1636. {
  1637. return RSA_HashSign(info->hashOid,info->key,sig,sigLen,maxLen,
  1638. hash,hashLen);
  1639. }
  1640. /* XXX Old template; want to expunge it eventually. */
  1641. static DERTemplate SECAlgorithmIDTemplate[] = {
  1642. { DER_SEQUENCE,
  1643. 0, NULL, sizeof(SECAlgorithmID) },
  1644. { DER_OBJECT_ID,
  1645. offsetof(SECAlgorithmID,algorithm), },
  1646. { DER_OPTIONAL | DER_ANY,
  1647. offsetof(SECAlgorithmID,parameters), },
  1648. { 0, }
  1649. };
  1650. /*
  1651. * XXX OLD Template. Once all uses have been switched over to new one,
  1652. * remove this.
  1653. */
  1654. static DERTemplate SGNDigestInfoTemplate[] = {
  1655. { DER_SEQUENCE,
  1656. 0, NULL, sizeof(SGNDigestInfo) },
  1657. { DER_INLINE,
  1658. offsetof(SGNDigestInfo,digestAlgorithm),
  1659. SECAlgorithmIDTemplate, },
  1660. { DER_OCTET_STRING,
  1661. offsetof(SGNDigestInfo,digest), },
  1662. { 0, }
  1663. };
  1664. SECStatus
  1665. RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
  1666. unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
  1667. unsigned char *hash, unsigned int hashLen)
  1668. {
  1669. SECStatus rv = SECFailure;
  1670. SECItem digder;
  1671. PLArenaPool *arena = NULL;
  1672. SGNDigestInfo *di = NULL;
  1673. digder.data = NULL;
  1674. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  1675. if ( !arena ) { goto loser; }
  1676. /* Construct digest info */
  1677. di = SGN_CreateDigestInfo(hashOid, hash, hashLen);
  1678. if (!di) { goto loser; }
  1679. /* Der encode the digest as a DigestInfo */
  1680. rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di);
  1681. if (rv != SECSuccess) {
  1682. goto loser;
  1683. }
  1684. /*
  1685. ** Encrypt signature after constructing appropriate PKCS#1 signature
  1686. ** block
  1687. */
  1688. rv = RSA_Sign(key,sig,sigLen,maxLen,digder.data,digder.len);
  1689. loser:
  1690. SGN_DestroyDigestInfo(di);
  1691. if (arena != NULL) {
  1692. PORT_FreeArena(arena, PR_FALSE);
  1693. }
  1694. return rv;
  1695. }
  1696. static SECStatus
  1697. sftk_SignPSS(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen,
  1698. unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
  1699. {
  1700. return RSA_SignPSS(info->params,info->key,sig,sigLen,maxLen,
  1701. hash,hashLen);
  1702. }
  1703. static SECStatus
  1704. nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen,
  1705. void *dataBuf, unsigned int dataLen)
  1706. {
  1707. SECItem signature, digest;
  1708. NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
  1709. signature.data = (unsigned char *)sigBuf;
  1710. signature.len = sigLen;
  1711. digest.data = (unsigned char *)dataBuf;
  1712. digest.len = dataLen;
  1713. return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest);
  1714. }
  1715. static SECStatus
  1716. nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
  1717. unsigned int *sigLen, unsigned int maxSigLen,
  1718. void *dataBuf, unsigned int dataLen)
  1719. {
  1720. SECItem signature, digest;
  1721. SECStatus rv;
  1722. NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
  1723. signature.data = (unsigned char *)sigBuf;
  1724. signature.len = maxSigLen;
  1725. digest.data = (unsigned char *)dataBuf;
  1726. digest.len = dataLen;
  1727. rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
  1728. if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
  1729. sftk_fatalError = PR_TRUE;
  1730. }
  1731. *sigLen = signature.len;
  1732. return rv;
  1733. }
  1734. #ifdef NSS_ENABLE_ECC
  1735. static SECStatus
  1736. nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
  1737. void *dataBuf, unsigned int dataLen)
  1738. {
  1739. SECItem signature, digest;
  1740. NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
  1741. signature.data = (unsigned char *)sigBuf;
  1742. signature.len = sigLen;
  1743. digest.data = (unsigned char *)dataBuf;
  1744. digest.len = dataLen;
  1745. return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest);
  1746. }
  1747. static SECStatus
  1748. nsc_ECDSASignStub(void *ctx, void *sigBuf,
  1749. unsigned int *sigLen, unsigned int maxSigLen,
  1750. void *dataBuf, unsigned int dataLen)
  1751. {
  1752. SECItem signature, digest;
  1753. SECStatus rv;
  1754. NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
  1755. signature.data = (unsigned char *)sigBuf;
  1756. signature.len = maxSigLen;
  1757. digest.data = (unsigned char *)dataBuf;
  1758. digest.len = dataLen;
  1759. rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
  1760. if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
  1761. sftk_fatalError = PR_TRUE;
  1762. }
  1763. *sigLen = signature.len;
  1764. return rv;
  1765. }
  1766. #endif /* NSS_ENABLE_ECC */
  1767. /* NSC_SignInit setups up the signing operations. There are three basic
  1768. * types of signing:
  1769. * (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
  1770. * to data in a single Sign operation (which often looks a lot like an
  1771. * encrypt, with data coming in and data going out).
  1772. * (2) Hash based signing, where we continually hash the data, then apply
  1773. * some sort of signature to the end.
  1774. * (3) Block Encryption CBC MAC's, where the Data is encrypted with a key,
  1775. * and only the final block is part of the mac.
  1776. *
  1777. * For case number 3, we initialize a context much like the Encryption Context
  1778. * (in fact we share code). We detect case 3 in C_SignUpdate, C_Sign, and
  1779. * C_Final by the following method... if it's not multi-part, and it's doesn't
  1780. * have a hash context, it must be a block Encryption CBC MAC.
  1781. *
  1782. * For case number 2, we initialize a hash structure, as well as make it
  1783. * multi-part. Updates are simple calls to the hash update function. Final
  1784. * calls the hashend, then passes the result to the 'update' function (which
  1785. * operates as a final signature function). In some hash based MAC'ing (as
  1786. * opposed to hash base signatures), the update function is can be simply a
  1787. * copy (as is the case with HMAC).
  1788. */
  1789. CK_RV NSC_SignInit(CK_SESSION_HANDLE hSession,
  1790. CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
  1791. {
  1792. SFTKSession *session;
  1793. SFTKObject *key;
  1794. SFTKSessionContext *context;
  1795. CK_KEY_TYPE key_type;
  1796. CK_RV crv = CKR_OK;
  1797. NSSLOWKEYPrivateKey *privKey;
  1798. SFTKHashSignInfo *info = NULL;
  1799. CHECK_FORK();
  1800. /* Block Cipher MACing Algorithms use a different Context init method..*/
  1801. crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN, SFTK_SIGN);
  1802. if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;
  1803. /* we're not using a block cipher mac */
  1804. session = sftk_SessionFromHandle(hSession);
  1805. if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
  1806. crv = sftk_InitGeneric(session,&context,SFTK_SIGN,&key,hKey,&key_type,
  1807. CKO_PRIVATE_KEY,CKA_SIGN);
  1808. if (crv != CKR_OK) {
  1809. sftk_FreeSession(session);
  1810. return crv;
  1811. }
  1812. context->multi = PR_FALSE;
  1813. #define INIT_RSA_SIGN_MECH(mmm) \
  1814. case CKM_ ## mmm ## _RSA_PKCS: \
  1815. context->multi = PR_TRUE; \
  1816. crv = sftk_doSub ## mmm (context); \
  1817. if (crv != CKR_OK) break; \
  1818. context->update = (SFTKCipher) sftk_HashSign; \
  1819. info = PORT_New(SFTKHashSignInfo); \
  1820. if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \
  1821. info->hashOid = SEC_OID_ ## mmm ; \
  1822. goto finish_rsa;
  1823. switch(pMechanism->mechanism) {
  1824. INIT_RSA_SIGN_MECH(MD5)
  1825. INIT_RSA_SIGN_MECH(MD2)
  1826. INIT_RSA_SIGN_MECH(SHA1)
  1827. INIT_RSA_SIGN_MECH(SHA224)
  1828. INIT_RSA_SIGN_MECH(SHA256)
  1829. INIT_RSA_SIGN_MECH(SHA384)
  1830. INIT_RSA_SIGN_MECH(SHA512)
  1831. case CKM_RSA_PKCS:
  1832. context->update = (SFTKCipher) RSA_Sign;
  1833. goto finish_rsa;
  1834. case CKM_RSA_X_509:
  1835. context->update = (SFTKCipher) RSA_SignRaw;
  1836. finish_rsa:
  1837. if (key_type != CKK_RSA) {
  1838. crv = CKR_KEY_TYPE_INCONSISTENT;
  1839. break;
  1840. }
  1841. privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
  1842. if (privKey == NULL) {
  1843. crv = CKR_KEY_TYPE_INCONSISTENT;
  1844. break;
  1845. }
  1846. /* OK, info is allocated only if we're doing hash and sign mechanism.
  1847. * It's necessary to be able to set the correct OID in the final
  1848. * signature.
  1849. */
  1850. if (info) {
  1851. info->key = privKey;
  1852. context->cipherInfo = info;
  1853. context->destroy = (SFTKDestroy)sftk_Space;
  1854. } else {
  1855. context->cipherInfo = privKey;
  1856. context->destroy = (SFTKDestroy)sftk_Null;
  1857. }
  1858. context->maxLen = nsslowkey_PrivateModulusLen(privKey);
  1859. break;
  1860. case CKM_RSA_PKCS_PSS:
  1861. if (key_type != CKK_RSA) {
  1862. crv = CKR_KEY_TYPE_INCONSISTENT;
  1863. break;
  1864. }
  1865. if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
  1866. crv = CKR_MECHANISM_PARAM_INVALID;
  1867. break;
  1868. }
  1869. info = PORT_New(SFTKHashSignInfo);
  1870. if (info == NULL) {
  1871. crv = CKR_HOST_MEMORY;
  1872. break;
  1873. }
  1874. info->params = pMechanism->pParameter;
  1875. info->key = sftk_GetPrivKey(key,CKK_RSA,&crv);
  1876. if (info->key == NULL) {
  1877. PORT_Free(info);
  1878. break;
  1879. }
  1880. context->cipherInfo = info;
  1881. context->destroy = (SFTKDestroy) sftk_Space;
  1882. context->update = (SFTKCipher) sftk_SignPSS;
  1883. context->maxLen = nsslowkey_PrivateModulusLen(info->key);
  1884. break;
  1885. case CKM_DSA_SHA1:
  1886. context->multi = PR_TRUE;
  1887. crv = sftk_doSubSHA1(context);
  1888. if (crv != CKR_OK) break;
  1889. /* fall through */
  1890. case CKM_DSA:
  1891. if (key_type != CKK_DSA) {
  1892. crv = CKR_KEY_TYPE_INCONSISTENT;
  1893. break;
  1894. }
  1895. privKey = sftk_GetPrivKey(key,CKK_DSA,&crv);
  1896. if (privKey == NULL) {
  1897. break;
  1898. }
  1899. context->cipherInfo = privKey;
  1900. context->update = (SFTKCipher) nsc_DSA_Sign_Stub;
  1901. context->destroy = (privKey == key->objectInfo) ?
  1902. (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey;
  1903. context->maxLen = DSA_SIGNATURE_LEN;
  1904. break;
  1905. #ifdef NSS_ENABLE_ECC
  1906. case CKM_ECDSA_SHA1:
  1907. context->multi = PR_TRUE;
  1908. crv = sftk_doSubSHA1(context);
  1909. if (crv != CKR_OK) break;
  1910. /* fall through */
  1911. case CKM_ECDSA:
  1912. if (key_type != CKK_EC) {
  1913. crv = CKR_KEY_TYPE_INCONSISTENT;
  1914. break;
  1915. }
  1916. privKey = sftk_GetPrivKey(key,CKK_EC,&crv);
  1917. if (privKey == NULL) {
  1918. crv = CKR_HOST_MEMORY;
  1919. break;
  1920. }
  1921. context->cipherInfo = privKey;
  1922. context->update = (SFTKCipher) nsc_ECDSASignStub;
  1923. context->destroy = (privKey == key->objectInfo) ?
  1924. (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey;
  1925. context->maxLen = MAX_ECKEY_LEN * 2;
  1926. break;
  1927. #endif /* NSS_ENABLE_ECC */
  1928. #define INIT_HMAC_MECH(mmm) \
  1929. case CKM_ ## mmm ## _HMAC_GENERAL: \
  1930. crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, \
  1931. *(CK_ULONG *)pMechanism->pParameter); \
  1932. break; \
  1933. case CKM_ ## mmm ## _HMAC: \
  1934. crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, mmm ## _LENGTH); \
  1935. break;
  1936. INIT_HMAC_MECH(MD2)
  1937. INIT_HMAC_MECH(MD5)
  1938. INIT_HMAC_MECH(SHA224)
  1939. INIT_HMAC_MECH(SHA256)
  1940. INIT_HMAC_MECH(SHA384)
  1941. INIT_HMAC_MECH(SHA512)
  1942. case CKM_SHA_1_HMAC_GENERAL:
  1943. crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,
  1944. *(CK_ULONG *)pMechanism->pParameter);
  1945. break;
  1946. case CKM_SHA_1_HMAC:
  1947. crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
  1948. break;
  1949. case CKM_SSL3_MD5_MAC:
  1950. crv = sftk_doSSLMACInit(context,SEC_OID_MD5,key,
  1951. *(CK_ULONG *)pMechanism->pParameter);
  1952. break;
  1953. case CKM_SSL3_SHA1_MAC:
  1954. crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key,
  1955. *(CK_ULONG *)pMechanism->pParameter);
  1956. break;
  1957. case CKM_TLS_PRF_GENERAL:
  1958. crv = sftk_TLSPRFInit(context, key, key_type);
  1959. break;
  1960. default:
  1961. crv = CKR_MECHANISM_INVALID;
  1962. break;
  1963. }
  1964. if (crv != CKR_OK) {
  1965. if (info) PORT_Free(info);
  1966. sftk_FreeContext(context);
  1967. sftk_FreeSession(session);
  1968. return crv;
  1969. }
  1970. sftk_SetContextByType(session, SFTK_SIGN, context);
  1971. sftk_FreeSession(session);
  1972. return CKR_OK;
  1973. }
  1974. /** MAC one block of data by block cipher
  1975. */
  1976. static CK_RV
  1977. sftk_MACBlock( SFTKSessionContext *ctx, void *blk )
  1978. {
  1979. unsigned int outlen;
  1980. return ( SECSuccess == (ctx->update)( ctx->cipherInfo, ctx->macBuf, &outlen,
  1981. SFTK_MAX_BLOCK_SIZE, blk, ctx->blockSize ))
  1982. ? CKR_OK : sftk_MapCryptError(PORT_GetError());
  1983. }
  1984. /** MAC last (incomplete) block of data by block cipher
  1985. *
  1986. * Call once, then terminate MACing operation.
  1987. */
  1988. static CK_RV
  1989. sftk_MACFinal( SFTKSessionContext *ctx )
  1990. {
  1991. unsigned int padLen = ctx->padDataLength;
  1992. /* pad and proceed the residual */
  1993. if( padLen ) {
  1994. /* shd clr ctx->padLen to make sftk_MACFinal idempotent */
  1995. PORT_Memset( ctx->padBuf + padLen, 0, ctx->blockSize - padLen );
  1996. return sftk_MACBlock( ctx, ctx->padBuf );
  1997. } else
  1998. return CKR_OK;
  1999. }
  2000. /** The common implementation for {Sign,Verify}Update. (S/V only vary in their
  2001. * setup and final operations).
  2002. *
  2003. * A call which results in an error terminates the operation [PKCS#11,v2.11]
  2004. */
  2005. static CK_RV
  2006. sftk_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
  2007. CK_ULONG ulPartLen,SFTKContextType type)
  2008. {
  2009. SFTKSession *session;
  2010. SFTKSessionContext *context;
  2011. CK_RV crv;
  2012. /* make sure we're legal */
  2013. crv = sftk_GetContext(hSession,&context,type, PR_TRUE, &session );
  2014. if (crv != CKR_OK) return crv;
  2015. if (context->hashInfo) {
  2016. (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen);
  2017. } else {
  2018. /* must be block cipher MACing */
  2019. unsigned int blkSize = context->blockSize;
  2020. unsigned char *residual = /* free room in context->padBuf */
  2021. context->padBuf + context->padDataLength;
  2022. unsigned int minInput = /* min input for MACing at least one block */
  2023. blkSize - context->padDataLength;
  2024. /* not enough data even for one block */
  2025. if( ulPartLen < minInput ) {
  2026. PORT_Memcpy( residual, pPart, ulPartLen );
  2027. context->padDataLength += ulPartLen;
  2028. goto cleanup;
  2029. }
  2030. /* MACing residual */
  2031. if( context->padDataLength ) {
  2032. PORT_Memcpy( residual, pPart, minInput );
  2033. ulPartLen -= minInput;
  2034. pPart += minInput;
  2035. if( CKR_OK != (crv = sftk_MACBlock( context, context->padBuf )) )
  2036. goto terminate;
  2037. }
  2038. /* MACing full blocks */
  2039. while( ulPartLen >= blkSize )
  2040. {
  2041. if( CKR_OK != (crv = sftk_MACBlock( context, pPart )) )
  2042. goto terminate;
  2043. ulPartLen -= blkSize;
  2044. pPart += blkSize;
  2045. }
  2046. /* save the residual */
  2047. if( (context->padDataLength = ulPartLen) )
  2048. PORT_Memcpy( context->padBuf, pPart, ulPartLen );
  2049. } /* blk cipher MACing */
  2050. goto cleanup;
  2051. terminate:
  2052. sftk_TerminateOp( session, type, context );
  2053. cleanup:
  2054. sftk_FreeSession(session);
  2055. return crv;
  2056. }
  2057. /* NSC_SignUpdate continues a multiple-part signature operation,
  2058. * where the signature is (will be) an appendix to the data,
  2059. * and plaintext cannot be recovered from the signature
  2060. *
  2061. * A call which results in an error terminates the operation [PKCS#11,v2.11]
  2062. */
  2063. CK_RV NSC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
  2064. CK_ULONG ulPartLen)
  2065. {
  2066. CHECK_FORK();
  2067. return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN);
  2068. }
  2069. /* NSC_SignFinal finishes a multiple-part signature operation,
  2070. * returning the signature. */
  2071. CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
  2072. CK_ULONG_PTR pulSignatureLen)
  2073. {
  2074. SFTKSession *session;
  2075. SFTKSessionContext *context;
  2076. unsigned int outlen;
  2077. unsigned int maxoutlen = *pulSignatureLen;
  2078. CK_RV crv;
  2079. CHECK_FORK();
  2080. /* make sure we're legal */
  2081. crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_TRUE,&session);
  2082. if (crv != CKR_OK) return crv;
  2083. if (context->hashInfo) {
  2084. unsigned int digestLen;
  2085. unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH];
  2086. if( !pSignature ) {
  2087. outlen = context->maxLen; goto finish;
  2088. }
  2089. (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
  2090. if( SECSuccess != (context->update)(context->cipherInfo, pSignature,
  2091. &outlen, maxoutlen, tmpbuf, digestLen))
  2092. crv = sftk_MapCryptError(PORT_GetError());
  2093. /* CKR_BUFFER_TOO_SMALL here isn't continuable, let operation terminate.
  2094. * Keeping "too small" CK_RV intact is a standard violation, but allows
  2095. * application read EXACT signature length */
  2096. } else {
  2097. /* must be block cipher MACing */
  2098. outlen = context->macSize;
  2099. /* null or "too small" buf doesn't terminate operation [PKCS#11,v2.11]*/
  2100. if( !pSignature || maxoutlen < outlen ) {
  2101. if( pSignature ) crv = CKR_BUFFER_TOO_SMALL;
  2102. goto finish;
  2103. }
  2104. if( CKR_OK == (crv = sftk_MACFinal( context )) )
  2105. PORT_Memcpy(pSignature, context->macBuf, outlen );
  2106. }
  2107. sftk_TerminateOp( session, SFTK_SIGN, context );
  2108. finish:
  2109. *pulSignatureLen = outlen;
  2110. sftk_FreeSession(session);
  2111. return crv;
  2112. }
  2113. /* NSC_Sign signs (encrypts with private key) data in a single part,
  2114. * where the signature is (will be) an appendix to the data,
  2115. * and plaintext cannot be recovered from the signature */
  2116. CK_RV NSC_Sign(CK_SESSION_HANDLE hSession,
  2117. CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,
  2118. CK_ULONG_PTR pulSignatureLen)
  2119. {
  2120. SFTKSession *session;
  2121. SFTKSessionContext *context;
  2122. CK_RV crv;
  2123. CHECK_FORK();
  2124. /* make sure we're legal */
  2125. crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_FALSE,&session);
  2126. if (crv != CKR_OK) return crv;
  2127. if (!pSignature) {
  2128. /* see also how C_SignUpdate implements this */
  2129. *pulSignatureLen = (!context->multi || context->hashInfo)
  2130. ? context->maxLen
  2131. : context->macSize; /* must be block cipher MACing */
  2132. goto finish;
  2133. }
  2134. /* multi part Signing are completely implemented by SignUpdate and
  2135. * sign Final */
  2136. if (context->multi) {
  2137. /* SignFinal can't follow failed SignUpdate */
  2138. if( CKR_OK == (crv = NSC_SignUpdate(hSession,pData,ulDataLen) ))
  2139. crv = NSC_SignFinal(hSession, pSignature, pulSignatureLen);
  2140. } else {
  2141. /* single-part PKC signature (e.g. CKM_ECDSA) */
  2142. unsigned int outlen;
  2143. unsigned int maxoutlen = *pulSignatureLen;
  2144. if( SECSuccess != (*context->update)(context->cipherInfo, pSignature,
  2145. &outlen, maxoutlen, pData, ulDataLen))
  2146. crv = sftk_MapCryptError(PORT_GetError());
  2147. *pulSignatureLen = (CK_ULONG) outlen;
  2148. /* "too small" here is certainly continuable */
  2149. if( crv != CKR_BUFFER_TOO_SMALL )
  2150. sftk_TerminateOp(session, SFTK_SIGN, context);
  2151. } /* single-part */
  2152. finish:
  2153. sftk_FreeSession(session);
  2154. return crv;
  2155. }
  2156. /*
  2157. ************** Crypto Functions: Sign Recover ************************
  2158. */
  2159. /* NSC_SignRecoverInit initializes a signature operation,
  2160. * where the (digest) data can be recovered from the signature.
  2161. * E.g. encryption with the user's private key */
  2162. CK_RV NSC_SignRecoverInit(CK_SESSION_HANDLE hSession,
  2163. CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
  2164. {
  2165. CHECK_FORK();
  2166. switch (pMechanism->mechanism) {
  2167. case CKM_RSA_PKCS:
  2168. case CKM_RSA_X_509:
  2169. return NSC_SignInit(hSession,pMechanism,hKey);
  2170. default:
  2171. break;
  2172. }
  2173. return CKR_MECHANISM_INVALID;
  2174. }
  2175. /* NSC_SignRecover signs data in a single operation
  2176. * where the (digest) data can be recovered from the signature.
  2177. * E.g. encryption with the user's private key */
  2178. CK_RV NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
  2179. CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
  2180. {
  2181. CHECK_FORK();
  2182. return NSC_Sign(hSession,pData,ulDataLen,pSignature,pulSignatureLen);
  2183. }
  2184. /*
  2185. ************** Crypto Functions: verify ************************
  2186. */
  2187. /* Handle RSA Signature formatting */
  2188. static SECStatus
  2189. sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig,
  2190. unsigned int sigLen, unsigned char *digest, unsigned int digestLen)
  2191. {
  2192. return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen,
  2193. digest, digestLen);
  2194. }
  2195. SECStatus
  2196. RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key,
  2197. unsigned char *sig, unsigned int sigLen,
  2198. unsigned char *digest, unsigned int digestLen)
  2199. {
  2200. SECItem it;
  2201. SGNDigestInfo *di = NULL;
  2202. SECStatus rv = SECSuccess;
  2203. it.data = NULL;
  2204. if (key == NULL) goto loser;
  2205. it.len = nsslowkey_PublicModulusLen(key);
  2206. if (!it.len) goto loser;
  2207. it.data = (unsigned char *) PORT_Alloc(it.len);
  2208. if (it.data == NULL) goto loser;
  2209. /* decrypt the block */
  2210. rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen);
  2211. if (rv != SECSuccess) goto loser;
  2212. di = SGN_DecodeDigestInfo(&it);
  2213. if (di == NULL) goto loser;
  2214. if (di->digest.len != digestLen) goto loser;
  2215. /* make sure the tag is OK */
  2216. if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) {
  2217. goto loser;
  2218. }
  2219. /* make sure the "parameters" are not too bogus. */
  2220. if (di->digestAlgorithm.parameters.len > 2) {
  2221. goto loser;
  2222. }
  2223. /* Now check the signature */
  2224. if (PORT_Memcmp(digest, di->digest.data, di->digest.len) == 0) {
  2225. goto done;
  2226. }
  2227. loser:
  2228. PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
  2229. rv = SECFailure;
  2230. done:
  2231. if (it.data != NULL) PORT_Free(it.data);
  2232. if (di != NULL) SGN_DestroyDigestInfo(di);
  2233. return rv;
  2234. }
  2235. static SECStatus
  2236. sftk_CheckSignPSS(SFTKHashVerifyInfo *info, unsigned char *sig,
  2237. unsigned int sigLen, unsigned char *digest, unsigned int digestLen)
  2238. {
  2239. return RSA_CheckSignPSS(info->params, info->key, sig, sigLen,
  2240. digest, digestLen);
  2241. }
  2242. /* NSC_VerifyInit initializes a verification operation,
  2243. * where the signature is an appendix to the data,
  2244. * and plaintext cannot be recovered from the signature (e.g. DSA) */
  2245. CK_RV NSC_VerifyInit(CK_SESSION_HANDLE hSession,
  2246. CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
  2247. {
  2248. SFTKSession *session;
  2249. SFTKObject *key;
  2250. SFTKSessionContext *context;
  2251. CK_KEY_TYPE key_type;
  2252. CK_RV crv = CKR_OK;
  2253. NSSLOWKEYPublicKey *pubKey;
  2254. SFTKHashVerifyInfo *info = NULL;
  2255. CHECK_FORK();
  2256. /* Block Cipher MACing Algorithms use a different Context init method..*/
  2257. crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY, SFTK_VERIFY);
  2258. if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;
  2259. session = sftk_SessionFromHandle(hSession);
  2260. if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
  2261. crv = sftk_InitGeneric(session,&context,SFTK_VERIFY,&key,hKey,&key_type,
  2262. CKO_PUBLIC_KEY,CKA_VERIFY);
  2263. if (crv != CKR_OK) {
  2264. sftk_FreeSession(session);
  2265. return crv;
  2266. }
  2267. context->multi = PR_FALSE;
  2268. #define INIT_RSA_VFY_MECH(mmm) \
  2269. case CKM_ ## mmm ## _RSA_PKCS: \
  2270. context->multi = PR_TRUE; \
  2271. crv = sftk_doSub ## mmm (context); \
  2272. if (crv != CKR_OK) break; \
  2273. context->verify = (SFTKVerify) sftk_hashCheckSign; \
  2274. info = PORT_New(SFTKHashVerifyInfo); \
  2275. if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \
  2276. info->hashOid = SEC_OID_ ## mmm ; \
  2277. goto finish_rsa;
  2278. switch(pMechanism->mechanism) {
  2279. INIT_RSA_VFY_MECH(MD5)
  2280. INIT_RSA_VFY_MECH(MD2)
  2281. INIT_RSA_VFY_MECH(SHA1)
  2282. INIT_RSA_VFY_MECH(SHA224)
  2283. INIT_RSA_VFY_MECH(SHA256)
  2284. INIT_RSA_VFY_MECH(SHA384)
  2285. INIT_RSA_VFY_MECH(SHA512)
  2286. case CKM_RSA_PKCS:
  2287. context->verify = (SFTKVerify) RSA_CheckSign;
  2288. goto finish_rsa;
  2289. case CKM_RSA_X_509:
  2290. context->verify = (SFTKVerify) RSA_CheckSignRaw;
  2291. finish_rsa:
  2292. if (key_type != CKK_RSA) {
  2293. if (info) PORT_Free(info);
  2294. crv = CKR_KEY_TYPE_INCONSISTENT;
  2295. break;
  2296. }
  2297. pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
  2298. if (pubKey == NULL) {
  2299. if (info) PORT_Free(info);
  2300. crv = CKR_KEY_TYPE_INCONSISTENT;
  2301. break;
  2302. }
  2303. if (info) {
  2304. info->key = pubKey;
  2305. context->cipherInfo = info;
  2306. context->destroy = sftk_Space;
  2307. } else {
  2308. context->cipherInfo = pubKey;
  2309. context->destroy = sftk_Null;
  2310. }
  2311. break;
  2312. case CKM_RSA_PKCS_PSS:
  2313. if (key_type != CKK_RSA) {
  2314. crv = CKR_KEY_TYPE_INCONSISTENT;
  2315. break;
  2316. }
  2317. if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
  2318. crv = CKR_MECHANISM_PARAM_INVALID;
  2319. break;
  2320. }
  2321. info = PORT_New(SFTKHashVerifyInfo);
  2322. if (info == NULL) {
  2323. crv = CKR_HOST_MEMORY;
  2324. break;
  2325. }
  2326. info->params = pMechanism->pParameter;
  2327. info->key = sftk_GetPubKey(key,CKK_RSA,&crv);
  2328. if (info->key == NULL) {
  2329. PORT_Free(info);
  2330. break;
  2331. }
  2332. context->cipherInfo = info;
  2333. context->destroy = (SFTKDestroy) sftk_Space;
  2334. context->verify = (SFTKVerify) sftk_CheckSignPSS;
  2335. break;
  2336. case CKM_DSA_SHA1:
  2337. context->multi = PR_TRUE;
  2338. crv = sftk_doSubSHA1(context);
  2339. if (crv != CKR_OK) break;
  2340. /* fall through */
  2341. case CKM_DSA:
  2342. if (key_type != CKK_DSA) {
  2343. crv = CKR_KEY_TYPE_INCONSISTENT;
  2344. break;
  2345. }
  2346. pubKey = sftk_GetPubKey(key,CKK_DSA,&crv);
  2347. if (pubKey == NULL) {
  2348. break;
  2349. }
  2350. context->cipherInfo = pubKey;
  2351. context->verify = (SFTKVerify) nsc_DSA_Verify_Stub;
  2352. context->destroy = sftk_Null;
  2353. break;
  2354. #ifdef NSS_ENABLE_ECC
  2355. case CKM_ECDSA_SHA1:
  2356. context->multi = PR_TRUE;
  2357. crv = sftk_doSubSHA1(context);
  2358. if (crv != CKR_OK) break;
  2359. /* fall through */
  2360. case CKM_ECDSA:
  2361. if (key_type != CKK_EC) {
  2362. crv = CKR_KEY_TYPE_INCONSISTENT;
  2363. break;
  2364. }
  2365. pubKey = sftk_GetPubKey(key,CKK_EC,&crv);
  2366. if (pubKey == NULL) {
  2367. crv = CKR_HOST_MEMORY;
  2368. break;
  2369. }
  2370. context->cipherInfo = pubKey;
  2371. context->verify = (SFTKVerify) nsc_ECDSAVerifyStub;
  2372. context->destroy = sftk_Null;
  2373. break;
  2374. #endif /* NSS_ENABLE_ECC */
  2375. INIT_HMAC_MECH(MD2)
  2376. INIT_HMAC_MECH(MD5)
  2377. INIT_HMAC_MECH(SHA224)
  2378. INIT_HMAC_MECH(SHA256)
  2379. INIT_HMAC_MECH(SHA384)
  2380. INIT_HMAC_MECH(SHA512)
  2381. case CKM_SHA_1_HMAC_GENERAL:
  2382. crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,
  2383. *(CK_ULONG *)pMechanism->pParameter);
  2384. break;
  2385. case CKM_SHA_1_HMAC:
  2386. crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
  2387. break;
  2388. case CKM_SSL3_MD5_MAC:
  2389. crv = sftk_doSSLMACInit(context,SEC_OID_MD5,key,
  2390. *(CK_ULONG *)pMechanism->pParameter);
  2391. break;
  2392. case CKM_SSL3_SHA1_MAC:
  2393. crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key,
  2394. *(CK_ULONG *)pMechanism->pParameter);
  2395. break;
  2396. case CKM_TLS_PRF_GENERAL:
  2397. crv = sftk_TLSPRFInit(context, key, key_type);
  2398. break;
  2399. default:
  2400. crv = CKR_MECHANISM_INVALID;
  2401. break;
  2402. }
  2403. if (crv != CKR_OK) {
  2404. if (info) PORT_Free(info);
  2405. sftk_FreeContext(context);
  2406. sftk_FreeSession(session);
  2407. return crv;
  2408. }
  2409. sftk_SetContextByType(session, SFTK_VERIFY, context);
  2410. sftk_FreeSession(session);
  2411. return CKR_OK;
  2412. }
  2413. /* NSC_Verify verifies a signature in a single-part operation,
  2414. * where the signature is an appendix to the data,
  2415. * and plaintext cannot be recovered from the signature */
  2416. CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
  2417. CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
  2418. {
  2419. SFTKSession *session;
  2420. SFTKSessionContext *context;
  2421. CK_RV crv;
  2422. CHECK_FORK();
  2423. /* make sure we're legal */
  2424. crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_FALSE,&session);
  2425. if (crv != CKR_OK) return crv;
  2426. /* multi part Verifying are completely implemented by VerifyUpdate and
  2427. * VerifyFinal */
  2428. if (context->multi) {
  2429. /* VerifyFinal can't follow failed VerifyUpdate */
  2430. if( CKR_OK == (crv = NSC_VerifyUpdate(hSession, pData, ulDataLen)))
  2431. crv = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen);
  2432. } else {
  2433. if (SECSuccess != (*context->verify)(context->cipherInfo,pSignature,
  2434. ulSignatureLen, pData, ulDataLen))
  2435. crv = sftk_MapCryptError(PORT_GetError());
  2436. sftk_TerminateOp( session, SFTK_VERIFY, context );
  2437. }
  2438. sftk_FreeSession(session);
  2439. return crv;
  2440. }
  2441. /* NSC_VerifyUpdate continues a multiple-part verification operation,
  2442. * where the signature is an appendix to the data,
  2443. * and plaintext cannot be recovered from the signature
  2444. *
  2445. * A call which results in an error terminates the operation [PKCS#11,v2.11]
  2446. */
  2447. CK_RV NSC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
  2448. CK_ULONG ulPartLen)
  2449. {
  2450. CHECK_FORK();
  2451. return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_VERIFY);
  2452. }
  2453. /* NSC_VerifyFinal finishes a multiple-part verification operation,
  2454. * checking the signature. */
  2455. CK_RV NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
  2456. CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)
  2457. {
  2458. SFTKSession *session;
  2459. SFTKSessionContext *context;
  2460. CK_RV crv;
  2461. CHECK_FORK();
  2462. if (!pSignature)
  2463. return CKR_ARGUMENTS_BAD;
  2464. /* make sure we're legal */
  2465. crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_TRUE,&session);
  2466. if (crv != CKR_OK)
  2467. return crv;
  2468. if (context->hashInfo) {
  2469. unsigned int digestLen;
  2470. unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH];
  2471. (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
  2472. if( SECSuccess != (context->verify)(context->cipherInfo, pSignature,
  2473. ulSignatureLen, tmpbuf, digestLen))
  2474. crv = sftk_MapCryptError(PORT_GetError());
  2475. } else if (ulSignatureLen != context->macSize) {
  2476. /* must be block cipher MACing */
  2477. crv = CKR_SIGNATURE_LEN_RANGE;
  2478. } else if (CKR_OK == (crv = sftk_MACFinal(context))) {
  2479. if (PORT_Memcmp(pSignature, context->macBuf, ulSignatureLen))
  2480. crv = CKR_SIGNATURE_INVALID;
  2481. }
  2482. sftk_TerminateOp( session, SFTK_VERIFY, context );
  2483. sftk_FreeSession(session);
  2484. return crv;
  2485. }
  2486. /*
  2487. ************** Crypto Functions: Verify Recover ************************
  2488. */
  2489. /* NSC_VerifyRecoverInit initializes a signature verification operation,
  2490. * where the data is recovered from the signature.
  2491. * E.g. Decryption with the user's public key */
  2492. CK_RV NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
  2493. CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
  2494. {
  2495. SFTKSession *session;
  2496. SFTKObject *key;
  2497. SFTKSessionContext *context;
  2498. CK_KEY_TYPE key_type;
  2499. CK_RV crv = CKR_OK;
  2500. NSSLOWKEYPublicKey *pubKey;
  2501. CHECK_FORK();
  2502. session = sftk_SessionFromHandle(hSession);
  2503. if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
  2504. crv = sftk_InitGeneric(session,&context,SFTK_VERIFY_RECOVER,
  2505. &key,hKey,&key_type,CKO_PUBLIC_KEY,CKA_VERIFY_RECOVER);
  2506. if (crv != CKR_OK) {
  2507. sftk_FreeSession(session);
  2508. return crv;
  2509. }
  2510. context->multi = PR_TRUE;
  2511. switch(pMechanism->mechanism) {
  2512. case CKM_RSA_PKCS:
  2513. case CKM_RSA_X_509:
  2514. if (key_type != CKK_RSA) {
  2515. crv = CKR_KEY_TYPE_INCONSISTENT;
  2516. break;
  2517. }
  2518. context->multi = PR_FALSE;
  2519. pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
  2520. if (pubKey == NULL) {
  2521. break;
  2522. }
  2523. context->cipherInfo = pubKey;
  2524. context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509
  2525. ? RSA_CheckSignRecoverRaw : RSA_CheckSignRecover);
  2526. context->destroy = sftk_Null;
  2527. break;
  2528. default:
  2529. crv = CKR_MECHANISM_INVALID;
  2530. break;
  2531. }
  2532. if (crv != CKR_OK) {
  2533. PORT_Free(context);
  2534. sftk_FreeSession(session);
  2535. return crv;
  2536. }
  2537. sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, context);
  2538. sftk_FreeSession(session);
  2539. return CKR_OK;
  2540. }
  2541. /* NSC_VerifyRecover verifies a signature in a single-part operation,
  2542. * where the data is recovered from the signature.
  2543. * E.g. Decryption with the user's public key */
  2544. CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession,
  2545. CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen,
  2546. CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)
  2547. {
  2548. SFTKSession *session;
  2549. SFTKSessionContext *context;
  2550. unsigned int outlen;
  2551. unsigned int maxoutlen = *pulDataLen;
  2552. CK_RV crv;
  2553. SECStatus rv;
  2554. CHECK_FORK();
  2555. /* make sure we're legal */
  2556. crv = sftk_GetContext(hSession,&context,SFTK_VERIFY_RECOVER,
  2557. PR_FALSE,&session);
  2558. if (crv != CKR_OK) return crv;
  2559. if (pData == NULL) {
  2560. /* to return the actual size, we need to do the decrypt, just return
  2561. * the max size, which is the size of the input signature. */
  2562. *pulDataLen = ulSignatureLen;
  2563. rv = SECSuccess;
  2564. goto finish;
  2565. }
  2566. rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
  2567. pSignature, ulSignatureLen);
  2568. *pulDataLen = (CK_ULONG) outlen;
  2569. sftk_TerminateOp(session, SFTK_VERIFY_RECOVER, context);
  2570. finish:
  2571. sftk_FreeSession(session);
  2572. return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError());
  2573. }
  2574. /*
  2575. **************************** Random Functions: ************************
  2576. */
  2577. /* NSC_SeedRandom mixes additional seed material into the token's random number
  2578. * generator. */
  2579. CK_RV NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
  2580. CK_ULONG ulSeedLen)
  2581. {
  2582. SECStatus rv;
  2583. CHECK_FORK();
  2584. rv = RNG_RandomUpdate(pSeed, ulSeedLen);
  2585. return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
  2586. }
  2587. /* NSC_GenerateRandom generates random data. */
  2588. CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
  2589. CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
  2590. {
  2591. SECStatus rv;
  2592. CHECK_FORK();
  2593. rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen);
  2594. /*
  2595. * This may fail with SEC_ERROR_NEED_RANDOM, which means the RNG isn't
  2596. * seeded with enough entropy.
  2597. */
  2598. return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
  2599. }
  2600. /*
  2601. **************************** Key Functions: ************************
  2602. */
  2603. /*
  2604. * generate a password based encryption key. This code uses
  2605. * PKCS5 to do the work.
  2606. */
  2607. static CK_RV
  2608. nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
  2609. void *buf, CK_ULONG *key_length, PRBool faulty3DES)
  2610. {
  2611. SECItem *pbe_key = NULL, iv, pwitem;
  2612. CK_PBE_PARAMS *pbe_params = NULL;
  2613. CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL;
  2614. *key_length = 0;
  2615. iv.data = NULL; iv.len = 0;
  2616. if (pMechanism->mechanism == CKM_PKCS5_PBKD2) {
  2617. pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
  2618. pwitem.data = (unsigned char *)pbkd2_params->pPassword;
  2619. /* was this a typo in the PKCS #11 spec? */
  2620. pwitem.len = *pbkd2_params->ulPasswordLen;
  2621. } else {
  2622. pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
  2623. pwitem.data = (unsigned char *)pbe_params->pPassword;
  2624. pwitem.len = pbe_params->ulPasswordLen;
  2625. }
  2626. pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES);
  2627. if (pbe_key == NULL) {
  2628. return CKR_HOST_MEMORY;
  2629. }
  2630. PORT_Memcpy(buf, pbe_key->data, pbe_key->len);
  2631. *key_length = pbe_key->len;
  2632. SECITEM_ZfreeItem(pbe_key, PR_TRUE);
  2633. pbe_key = NULL;
  2634. if (iv.data) {
  2635. if (pbe_params && pbe_params->pInitVector != NULL) {
  2636. PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
  2637. }
  2638. PORT_Free(iv.data);
  2639. }
  2640. return CKR_OK;
  2641. }
  2642. static CK_RV
  2643. nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
  2644. {
  2645. SFTKAttribute *attribute;
  2646. CK_ULONG counter;
  2647. unsigned int seedBits = 0;
  2648. unsigned int primeBits;
  2649. unsigned int j;
  2650. CK_RV crv = CKR_OK;
  2651. PQGParams *params = NULL;
  2652. PQGVerify *vfy = NULL;
  2653. SECStatus rv;
  2654. attribute = sftk_FindAttribute(key, CKA_PRIME_BITS);
  2655. if (attribute == NULL) {
  2656. return CKR_TEMPLATE_INCOMPLETE;
  2657. }
  2658. primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
  2659. sftk_FreeAttribute(attribute);
  2660. j = PQG_PBITS_TO_INDEX(primeBits);
  2661. if (j == (unsigned int)-1) {
  2662. return CKR_ATTRIBUTE_VALUE_INVALID;
  2663. }
  2664. attribute = sftk_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS);
  2665. if (attribute != NULL) {
  2666. seedBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
  2667. sftk_FreeAttribute(attribute);
  2668. }
  2669. sftk_DeleteAttributeType(key,CKA_PRIME_BITS);
  2670. sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS);
  2671. if (seedBits == 0) {
  2672. rv = PQG_ParamGen(j, &params, &vfy);
  2673. } else {
  2674. rv = PQG_ParamGenSeedLen(j,seedBits/8, &params, &vfy);
  2675. }
  2676. if (rv != SECSuccess) {
  2677. if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
  2678. sftk_fatalError = PR_TRUE;
  2679. }
  2680. return sftk_MapCryptError(PORT_GetError());
  2681. }
  2682. crv = sftk_AddAttributeType(key,CKA_PRIME,
  2683. params->prime.data, params->prime.len);
  2684. if (crv != CKR_OK) goto loser;
  2685. crv = sftk_AddAttributeType(key,CKA_SUBPRIME,
  2686. params->subPrime.data, params->subPrime.len);
  2687. if (crv != CKR_OK) goto loser;
  2688. crv = sftk_AddAttributeType(key,CKA_BASE,
  2689. params->base.data, params->base.len);
  2690. if (crv != CKR_OK) goto loser;
  2691. counter = vfy->counter;
  2692. crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_COUNTER,
  2693. &counter, sizeof(counter));
  2694. crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_SEED,
  2695. vfy->seed.data, vfy->seed.len);
  2696. if (crv != CKR_OK) goto loser;
  2697. crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_H,
  2698. vfy->h.data, vfy->h.len);
  2699. if (crv != CKR_OK) goto loser;
  2700. loser:
  2701. PQG_DestroyParams(params);
  2702. if (vfy) {
  2703. PQG_DestroyVerify(vfy);
  2704. }
  2705. return crv;
  2706. }
  2707. static CK_RV
  2708. nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type,
  2709. CK_ULONG *key_length)
  2710. {
  2711. CK_RV crv = CKR_OK;
  2712. switch (mechanism) {
  2713. case CKM_RC2_KEY_GEN:
  2714. *key_type = CKK_RC2;
  2715. if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
  2716. break;
  2717. #if NSS_SOFTOKEN_DOES_RC5
  2718. case CKM_RC5_KEY_GEN:
  2719. *key_type = CKK_RC5;
  2720. if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
  2721. break;
  2722. #endif
  2723. case CKM_RC4_KEY_GEN:
  2724. *key_type = CKK_RC4;
  2725. if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
  2726. break;
  2727. case CKM_GENERIC_SECRET_KEY_GEN:
  2728. *key_type = CKK_GENERIC_SECRET;
  2729. if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
  2730. break;
  2731. case CKM_CDMF_KEY_GEN:
  2732. *key_type = CKK_CDMF;
  2733. *key_length = 8;
  2734. break;
  2735. case CKM_DES_KEY_GEN:
  2736. *key_type = CKK_DES;
  2737. *key_length = 8;
  2738. break;
  2739. case CKM_DES2_KEY_GEN:
  2740. *key_type = CKK_DES2;
  2741. *key_length = 16;
  2742. break;
  2743. case CKM_DES3_KEY_GEN:
  2744. *key_type = CKK_DES3;
  2745. *key_length = 24;
  2746. break;
  2747. case CKM_SEED_KEY_GEN:
  2748. *key_type = CKK_SEED;
  2749. *key_length = 16;
  2750. break;
  2751. case CKM_CAMELLIA_KEY_GEN:
  2752. *key_type = CKK_CAMELLIA;
  2753. if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
  2754. break;
  2755. case CKM_AES_KEY_GEN:
  2756. *key_type = CKK_AES;
  2757. if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
  2758. break;
  2759. default:
  2760. PORT_Assert(0);
  2761. crv = CKR_MECHANISM_INVALID;
  2762. break;
  2763. }
  2764. return crv;
  2765. }
  2766. CK_RV
  2767. nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
  2768. {
  2769. SECItem salt;
  2770. CK_PBE_PARAMS *pbe_params = NULL;
  2771. NSSPKCS5PBEParameter *params;
  2772. PRArenaPool *arena = NULL;
  2773. SECStatus rv;
  2774. *pbe = NULL;
  2775. arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
  2776. if (arena == NULL) {
  2777. return CKR_HOST_MEMORY;
  2778. }
  2779. params = (NSSPKCS5PBEParameter *) PORT_ArenaZAlloc(arena,
  2780. sizeof(NSSPKCS5PBEParameter));
  2781. if (params == NULL) {
  2782. PORT_FreeArena(arena,PR_TRUE);
  2783. return CKR_HOST_MEMORY;
  2784. }
  2785. params->poolp = arena;
  2786. params->ivLen = 0;
  2787. params->pbeType = NSSPKCS5_PKCS12_V2;
  2788. params->hashType = HASH_AlgSHA1;
  2789. params->encAlg = SEC_OID_SHA1; /* any invalid value */
  2790. params->is2KeyDES = PR_FALSE;
  2791. params->keyID = pbeBitGenIntegrityKey;
  2792. pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
  2793. params->iter = pbe_params->ulIteration;
  2794. salt.data = (unsigned char *)pbe_params->pSalt;
  2795. salt.len = (unsigned int)pbe_params->ulSaltLen;
  2796. rv = SECITEM_CopyItem(arena,&params->salt,&salt);
  2797. if (rv != SECSuccess) {
  2798. PORT_FreeArena(arena,PR_TRUE);
  2799. return CKR_HOST_MEMORY;
  2800. }
  2801. switch (pMechanism->mechanism) {
  2802. case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
  2803. case CKM_PBA_SHA1_WITH_SHA1_HMAC:
  2804. params->hashType = HASH_AlgSHA1;
  2805. params->keyLen = 20;
  2806. break;
  2807. case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
  2808. params->hashType = HASH_AlgMD5;
  2809. params->keyLen = 16;
  2810. break;
  2811. case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
  2812. params->hashType = HASH_AlgMD2;
  2813. params->keyLen = 16;
  2814. break;
  2815. default:
  2816. PORT_FreeArena(arena,PR_TRUE);
  2817. return CKR_MECHANISM_INVALID;
  2818. }
  2819. *pbe = params;
  2820. return CKR_OK;
  2821. }
  2822. /* maybe this should be table driven? */
  2823. static CK_RV
  2824. nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
  2825. CK_KEY_TYPE *key_type, CK_ULONG *key_length)
  2826. {
  2827. CK_RV crv = CKR_OK;
  2828. SECOidData *oid;
  2829. CK_PBE_PARAMS *pbe_params = NULL;
  2830. NSSPKCS5PBEParameter *params = NULL;
  2831. CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL;
  2832. SECItem salt;
  2833. CK_ULONG iteration = 0;
  2834. *pbe = NULL;
  2835. oid = SECOID_FindOIDByMechanism(pMechanism->mechanism);
  2836. if (oid == NULL) {
  2837. return CKR_MECHANISM_INVALID;
  2838. }
  2839. if (pMechanism->mechanism == CKM_PKCS5_PBKD2) {
  2840. pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
  2841. if (pbkd2_params->saltSource != CKZ_SALT_SPECIFIED) {
  2842. return CKR_MECHANISM_PARAM_INVALID;
  2843. }
  2844. salt.data = (unsigned char *)pbkd2_params->pSaltSourceData;
  2845. salt.len = (unsigned int)pbkd2_params->ulSaltSourceDataLen;
  2846. iteration = pbkd2_params->iterations;
  2847. } else {
  2848. pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
  2849. salt.data = (unsigned char *)pbe_params->pSalt;
  2850. salt.len = (unsigned int)pbe_params->ulSaltLen;
  2851. iteration = pbe_params->ulIteration;
  2852. }
  2853. params=nsspkcs5_NewParam(oid->offset, &salt, iteration);
  2854. if (params == NULL) {
  2855. return CKR_MECHANISM_INVALID;
  2856. }
  2857. switch (params->encAlg) {
  2858. case SEC_OID_DES_CBC:
  2859. *key_type = CKK_DES;
  2860. *key_length = params->keyLen;
  2861. break;
  2862. case SEC_OID_DES_EDE3_CBC:
  2863. *key_type = params->is2KeyDES ? CKK_DES2 : CKK_DES3;
  2864. *key_length = params->keyLen;
  2865. break;
  2866. case SEC_OID_RC2_CBC:
  2867. *key_type = CKK_RC2;
  2868. *key_length = params->keyLen;
  2869. break;
  2870. case SEC_OID_RC4:
  2871. *key_type = CKK_RC4;
  2872. *key_length = params->keyLen;
  2873. break;
  2874. case SEC_OID_PKCS5_PBKDF2:
  2875. /* sigh, PKCS #11 currently only defines SHA1 for the KDF hash type.
  2876. * we do the check here because this where we would handle multiple
  2877. * hash types in the future */
  2878. if (pbkd2_params == NULL ||
  2879. pbkd2_params->prf != CKP_PKCS5_PBKD2_HMAC_SHA1) {
  2880. crv = CKR_MECHANISM_PARAM_INVALID;
  2881. break;
  2882. }
  2883. /* key type must already be set */
  2884. if (*key_type == CKK_INVALID_KEY_TYPE) {
  2885. crv = CKR_TEMPLATE_INCOMPLETE;
  2886. break;
  2887. }
  2888. /* PBKDF2 needs to calculate the key length from the other parameters
  2889. */
  2890. if (*key_length == 0) {
  2891. *key_length = sftk_MapKeySize(*key_type);
  2892. }
  2893. if (*key_length == 0) {
  2894. crv = CKR_TEMPLATE_INCOMPLETE;
  2895. break;
  2896. }
  2897. params->keyLen = *key_length;
  2898. break;
  2899. default:
  2900. crv = CKR_MECHANISM_INVALID;
  2901. nsspkcs5_DestroyPBEParameter(params);
  2902. break;
  2903. }
  2904. if (crv == CKR_OK) {
  2905. *pbe = params;
  2906. }
  2907. return crv;
  2908. }
  2909. /* NSC_GenerateKey generates a secret key, creating a new key object. */
  2910. CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
  2911. CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
  2912. CK_OBJECT_HANDLE_PTR phKey)
  2913. {
  2914. SFTKObject *key;
  2915. SFTKSession *session;
  2916. PRBool checkWeak = PR_FALSE;
  2917. CK_ULONG key_length = 0;
  2918. CK_KEY_TYPE key_type = CKK_INVALID_KEY_TYPE;
  2919. CK_OBJECT_CLASS objclass = CKO_SECRET_KEY;
  2920. CK_RV crv = CKR_OK;
  2921. CK_BBOOL cktrue = CK_TRUE;
  2922. int i;
  2923. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  2924. unsigned char buf[MAX_KEY_LEN];
  2925. enum {nsc_pbe, nsc_ssl, nsc_bulk, nsc_param, nsc_jpake} key_gen_type;
  2926. NSSPKCS5PBEParameter *pbe_param;
  2927. SSL3RSAPreMasterSecret *rsa_pms;
  2928. CK_VERSION *version;
  2929. /* in very old versions of NSS, there were implementation errors with key
  2930. * generation methods. We want to beable to read these, but not
  2931. * produce them any more. The affected algorithm was 3DES.
  2932. */
  2933. PRBool faultyPBE3DES = PR_FALSE;
  2934. HASH_HashType hashType;
  2935. CHECK_FORK();
  2936. if (!slot) {
  2937. return CKR_SESSION_HANDLE_INVALID;
  2938. }
  2939. /*
  2940. * now lets create an object to hang the attributes off of
  2941. */
  2942. key = sftk_NewObject(slot); /* fill in the handle later */
  2943. if (key == NULL) {
  2944. return CKR_HOST_MEMORY;
  2945. }
  2946. /*
  2947. * load the template values into the object
  2948. */
  2949. for (i=0; i < (int) ulCount; i++) {
  2950. if (pTemplate[i].type == CKA_VALUE_LEN) {
  2951. key_length = *(CK_ULONG *)pTemplate[i].pValue;
  2952. continue;
  2953. }
  2954. /* some algorithms need keytype specified */
  2955. if (pTemplate[i].type == CKA_KEY_TYPE) {
  2956. key_type = *(CK_ULONG *)pTemplate[i].pValue;
  2957. continue;
  2958. }
  2959. crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
  2960. if (crv != CKR_OK) break;
  2961. }
  2962. if (crv != CKR_OK) {
  2963. sftk_FreeObject(key);
  2964. return crv;
  2965. }
  2966. /* make sure we don't have any class, key_type, or value fields */
  2967. sftk_DeleteAttributeType(key,CKA_CLASS);
  2968. sftk_DeleteAttributeType(key,CKA_KEY_TYPE);
  2969. sftk_DeleteAttributeType(key,CKA_VALUE);
  2970. /* Now Set up the parameters to generate the key (based on mechanism) */
  2971. key_gen_type = nsc_bulk; /* bulk key by default */
  2972. switch (pMechanism->mechanism) {
  2973. case CKM_CDMF_KEY_GEN:
  2974. case CKM_DES_KEY_GEN:
  2975. case CKM_DES2_KEY_GEN:
  2976. case CKM_DES3_KEY_GEN:
  2977. checkWeak = PR_TRUE;
  2978. case CKM_RC2_KEY_GEN:
  2979. case CKM_RC4_KEY_GEN:
  2980. case CKM_GENERIC_SECRET_KEY_GEN:
  2981. case CKM_SEED_KEY_GEN:
  2982. case CKM_CAMELLIA_KEY_GEN:
  2983. case CKM_AES_KEY_GEN:
  2984. #if NSS_SOFTOKEN_DOES_RC5
  2985. case CKM_RC5_KEY_GEN:
  2986. #endif
  2987. crv = nsc_SetupBulkKeyGen(pMechanism->mechanism,&key_type,&key_length);
  2988. break;
  2989. case CKM_SSL3_PRE_MASTER_KEY_GEN:
  2990. key_type = CKK_GENERIC_SECRET;
  2991. key_length = 48;
  2992. key_gen_type = nsc_ssl;
  2993. break;
  2994. case CKM_PBA_SHA1_WITH_SHA1_HMAC:
  2995. case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
  2996. case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
  2997. case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
  2998. key_gen_type = nsc_pbe;
  2999. key_type = CKK_GENERIC_SECRET;
  3000. crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param);
  3001. break;
  3002. case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
  3003. faultyPBE3DES = PR_TRUE;
  3004. case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
  3005. case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
  3006. case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
  3007. case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
  3008. case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
  3009. case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
  3010. case CKM_PBE_SHA1_DES3_EDE_CBC:
  3011. case CKM_PBE_SHA1_DES2_EDE_CBC:
  3012. case CKM_PBE_SHA1_RC2_128_CBC:
  3013. case CKM_PBE_SHA1_RC2_40_CBC:
  3014. case CKM_PBE_SHA1_RC4_128:
  3015. case CKM_PBE_SHA1_RC4_40:
  3016. case CKM_PBE_MD5_DES_CBC:
  3017. case CKM_PBE_MD2_DES_CBC:
  3018. case CKM_PKCS5_PBKD2:
  3019. key_gen_type = nsc_pbe;
  3020. crv = nsc_SetupPBEKeyGen(pMechanism,&pbe_param, &key_type, &key_length);
  3021. break;
  3022. case CKM_DSA_PARAMETER_GEN:
  3023. key_gen_type = nsc_param;
  3024. key_type = CKK_DSA;
  3025. objclass = CKO_KG_PARAMETERS;
  3026. crv = CKR_OK;
  3027. break;
  3028. case CKM_NSS_JPAKE_ROUND1_SHA1: hashType = HASH_AlgSHA1; goto jpake1;
  3029. case CKM_NSS_JPAKE_ROUND1_SHA256: hashType = HASH_AlgSHA256; goto jpake1;
  3030. case CKM_NSS_JPAKE_ROUND1_SHA384: hashType = HASH_AlgSHA384; goto jpake1;
  3031. case CKM_NSS_JPAKE_ROUND1_SHA512: hashType = HASH_AlgSHA512; goto jpake1;
  3032. jpake1:
  3033. key_gen_type = nsc_jpake;
  3034. key_type = CKK_NSS_JPAKE_ROUND1;
  3035. objclass = CKO_PRIVATE_KEY;
  3036. if (pMechanism->pParameter == NULL ||
  3037. pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound1Params)) {
  3038. crv = CKR_MECHANISM_PARAM_INVALID;
  3039. break;
  3040. }
  3041. if (sftk_isTrue(key, CKA_TOKEN)) {
  3042. crv = CKR_TEMPLATE_INCONSISTENT;
  3043. }
  3044. crv = CKR_OK;
  3045. break;
  3046. default:
  3047. crv = CKR_MECHANISM_INVALID;
  3048. break;
  3049. }
  3050. /* make sure we aren't going to overflow the buffer */
  3051. if (sizeof(buf) < key_length) {
  3052. /* someone is getting pretty optimistic about how big their key can
  3053. * be... */
  3054. crv = CKR_TEMPLATE_INCONSISTENT;
  3055. }
  3056. if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
  3057. /* if there was no error,
  3058. * key_type *MUST* be set in the switch statement above */
  3059. PORT_Assert( key_type != CKK_INVALID_KEY_TYPE );
  3060. /*
  3061. * now to the actual key gen.
  3062. */
  3063. switch (key_gen_type) {
  3064. case nsc_pbe:
  3065. crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length,
  3066. faultyPBE3DES);
  3067. nsspkcs5_DestroyPBEParameter(pbe_param);
  3068. break;
  3069. case nsc_ssl:
  3070. rsa_pms = (SSL3RSAPreMasterSecret *)buf;
  3071. version = (CK_VERSION *)pMechanism->pParameter;
  3072. rsa_pms->client_version[0] = version->major;
  3073. rsa_pms->client_version[1] = version->minor;
  3074. crv =
  3075. NSC_GenerateRandom(0,&rsa_pms->random[0], sizeof(rsa_pms->random));
  3076. break;
  3077. case nsc_bulk:
  3078. /* get the key, check for weak keys and repeat if found */
  3079. do {
  3080. crv = NSC_GenerateRandom(0, buf, key_length);
  3081. } while (crv == CKR_OK && checkWeak && sftk_IsWeakKey(buf,key_type));
  3082. break;
  3083. case nsc_param:
  3084. /* generate parameters */
  3085. *buf = 0;
  3086. crv = nsc_parameter_gen(key_type,key);
  3087. break;
  3088. case nsc_jpake:
  3089. crv = jpake_Round1(hashType,
  3090. (CK_NSS_JPAKERound1Params *) pMechanism->pParameter,
  3091. key);
  3092. break;
  3093. }
  3094. if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
  3095. /* Add the class, key_type, and value */
  3096. crv = sftk_AddAttributeType(key,CKA_CLASS,&objclass,sizeof(CK_OBJECT_CLASS));
  3097. if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
  3098. crv = sftk_AddAttributeType(key,CKA_KEY_TYPE,&key_type,sizeof(CK_KEY_TYPE));
  3099. if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
  3100. if (key_length != 0) {
  3101. crv = sftk_AddAttributeType(key,CKA_VALUE,buf,key_length);
  3102. if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
  3103. }
  3104. /* get the session */
  3105. session = sftk_SessionFromHandle(hSession);
  3106. if (session == NULL) {
  3107. sftk_FreeObject(key);
  3108. return CKR_SESSION_HANDLE_INVALID;
  3109. }
  3110. /*
  3111. * handle the base object stuff
  3112. */
  3113. crv = sftk_handleObject(key,session);
  3114. sftk_FreeSession(session);
  3115. if (sftk_isTrue(key,CKA_SENSITIVE)) {
  3116. sftk_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
  3117. }
  3118. if (!sftk_isTrue(key,CKA_EXTRACTABLE)) {
  3119. sftk_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
  3120. }
  3121. *phKey = key->handle;
  3122. sftk_FreeObject(key);
  3123. return crv;
  3124. }
  3125. #define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
  3126. #define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
  3127. /*
  3128. * FIPS 140-2 pairwise consistency check utilized to validate key pair.
  3129. *
  3130. * This function returns
  3131. * CKR_OK if pairwise consistency check passed
  3132. * CKR_GENERAL_ERROR if pairwise consistency check failed
  3133. * other error codes if paiswise consistency check could not be
  3134. * performed, for example, CKR_HOST_MEMORY.
  3135. */
  3136. static CK_RV
  3137. sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
  3138. SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType)
  3139. {
  3140. /*
  3141. * Key type Mechanism type
  3142. * --------------------------------
  3143. * For encrypt/decrypt: CKK_RSA => CKM_RSA_PKCS
  3144. * others => CKM_INVALID_MECHANISM
  3145. *
  3146. * For sign/verify: CKK_RSA => CKM_RSA_PKCS
  3147. * CKK_DSA => CKM_DSA
  3148. * CKK_EC => CKM_ECDSA
  3149. * others => CKM_INVALID_MECHANISM
  3150. *
  3151. * None of these mechanisms has a parameter.
  3152. */
  3153. CK_MECHANISM mech = {0, NULL, 0};
  3154. CK_ULONG modulusLen;
  3155. PRBool isEncryptable = PR_FALSE;
  3156. PRBool canSignVerify = PR_FALSE;
  3157. PRBool isDerivable = PR_FALSE;
  3158. CK_RV crv;
  3159. /* Variables used for Encrypt/Decrypt functions. */
  3160. unsigned char *known_message = (unsigned char *)"Known Crypto Message";
  3161. unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH];
  3162. CK_ULONG bytes_decrypted;
  3163. unsigned char *ciphertext;
  3164. unsigned char *text_compared;
  3165. CK_ULONG bytes_encrypted;
  3166. CK_ULONG bytes_compared;
  3167. /* Variables used for Signature/Verification functions. */
  3168. /* always uses SHA-1 digest */
  3169. unsigned char *known_digest = (unsigned char *)"Mozilla Rules World!";
  3170. unsigned char *signature;
  3171. CK_ULONG signature_length;
  3172. if (keyType == CKK_RSA) {
  3173. SFTKAttribute *attribute;
  3174. /* Get modulus length of private key. */
  3175. attribute = sftk_FindAttribute(privateKey, CKA_MODULUS);
  3176. if (attribute == NULL) {
  3177. return CKR_DEVICE_ERROR;
  3178. }
  3179. modulusLen = attribute->attrib.ulValueLen;
  3180. if (*(unsigned char *)attribute->attrib.pValue == 0) {
  3181. modulusLen--;
  3182. }
  3183. sftk_FreeAttribute(attribute);
  3184. }
  3185. /**************************************************/
  3186. /* Pairwise Consistency Check of Encrypt/Decrypt. */
  3187. /**************************************************/
  3188. isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT);
  3189. /*
  3190. * If the decryption attribute is set, attempt to encrypt
  3191. * with the public key and decrypt with the private key.
  3192. */
  3193. if (isEncryptable) {
  3194. if (keyType != CKK_RSA) {
  3195. return CKR_DEVICE_ERROR;
  3196. }
  3197. bytes_encrypted = modulusLen;
  3198. mech.mechanism = CKM_RSA_PKCS;
  3199. /* Allocate space for ciphertext. */
  3200. ciphertext = (unsigned char *) PORT_ZAlloc(bytes_encrypted);
  3201. if (ciphertext == NULL) {
  3202. return CKR_HOST_MEMORY;
  3203. }
  3204. /* Prepare for encryption using the public key. */
  3205. crv = NSC_EncryptInit(hSession, &mech, publicKey->handle);
  3206. if (crv != CKR_OK) {
  3207. PORT_Free(ciphertext);
  3208. return crv;
  3209. }
  3210. /* Encrypt using the public key. */
  3211. crv = NSC_Encrypt(hSession,
  3212. known_message,
  3213. PAIRWISE_MESSAGE_LENGTH,
  3214. ciphertext,
  3215. &bytes_encrypted);
  3216. if (crv != CKR_OK) {
  3217. PORT_Free(ciphertext);
  3218. return crv;
  3219. }
  3220. /* Always use the smaller of these two values . . . */
  3221. bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH);
  3222. /*
  3223. * If there was a failure, the plaintext
  3224. * goes at the end, therefore . . .
  3225. */
  3226. text_compared = ciphertext + bytes_encrypted - bytes_compared;
  3227. /*
  3228. * Check to ensure that ciphertext does
  3229. * NOT EQUAL known input message text
  3230. * per FIPS PUB 140-2 directive.
  3231. */
  3232. if (PORT_Memcmp(text_compared, known_message,
  3233. bytes_compared) == 0) {
  3234. /* Set error to Invalid PRIVATE Key. */
  3235. PORT_SetError(SEC_ERROR_INVALID_KEY);
  3236. PORT_Free(ciphertext);
  3237. return CKR_GENERAL_ERROR;
  3238. }
  3239. /* Prepare for decryption using the private key. */
  3240. crv = NSC_DecryptInit(hSession, &mech, privateKey->handle);
  3241. if (crv != CKR_OK) {
  3242. PORT_Free(ciphertext);
  3243. return crv;
  3244. }
  3245. memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH);
  3246. /*
  3247. * Initialize bytes decrypted to be the
  3248. * expected PAIRWISE_MESSAGE_LENGTH.
  3249. */
  3250. bytes_decrypted = PAIRWISE_MESSAGE_LENGTH;
  3251. /*
  3252. * Decrypt using the private key.
  3253. * NOTE: No need to reset the
  3254. * value of bytes_encrypted.
  3255. */
  3256. crv = NSC_Decrypt(hSession,
  3257. ciphertext,
  3258. bytes_encrypted,
  3259. plaintext,
  3260. &bytes_decrypted);
  3261. /* Finished with ciphertext; free it. */
  3262. PORT_Free(ciphertext);
  3263. if (crv != CKR_OK) {
  3264. return crv;
  3265. }
  3266. /*
  3267. * Check to ensure that the output plaintext
  3268. * does EQUAL known input message text.
  3269. */
  3270. if ((bytes_decrypted != PAIRWISE_MESSAGE_LENGTH) ||
  3271. (PORT_Memcmp(plaintext, known_message,
  3272. PAIRWISE_MESSAGE_LENGTH) != 0)) {
  3273. /* Set error to Bad PUBLIC Key. */
  3274. PORT_SetError(SEC_ERROR_BAD_KEY);
  3275. return CKR_GENERAL_ERROR;
  3276. }
  3277. }
  3278. /**********************************************/
  3279. /* Pairwise Consistency Check of Sign/Verify. */
  3280. /**********************************************/
  3281. canSignVerify = sftk_isTrue(privateKey, CKA_SIGN);
  3282. if (canSignVerify) {
  3283. /* Determine length of signature. */
  3284. switch (keyType) {
  3285. case CKK_RSA:
  3286. signature_length = modulusLen;
  3287. mech.mechanism = CKM_RSA_PKCS;
  3288. break;
  3289. case CKK_DSA:
  3290. signature_length = DSA_SIGNATURE_LEN;
  3291. mech.mechanism = CKM_DSA;
  3292. break;
  3293. #ifdef NSS_ENABLE_ECC
  3294. case CKK_EC:
  3295. signature_length = MAX_ECKEY_LEN * 2;
  3296. mech.mechanism = CKM_ECDSA;
  3297. break;
  3298. #endif
  3299. default:
  3300. return CKR_DEVICE_ERROR;
  3301. }
  3302. /* Allocate space for signature data. */
  3303. signature = (unsigned char *) PORT_ZAlloc(signature_length);
  3304. if (signature == NULL) {
  3305. return CKR_HOST_MEMORY;
  3306. }
  3307. /* Sign the known hash using the private key. */
  3308. crv = NSC_SignInit(hSession, &mech, privateKey->handle);
  3309. if (crv != CKR_OK) {
  3310. PORT_Free(signature);
  3311. return crv;
  3312. }
  3313. crv = NSC_Sign(hSession,
  3314. known_digest,
  3315. PAIRWISE_DIGEST_LENGTH,
  3316. signature,
  3317. &signature_length);
  3318. if (crv != CKR_OK) {
  3319. PORT_Free(signature);
  3320. return crv;
  3321. }
  3322. /* Verify the known hash using the public key. */
  3323. crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
  3324. if (crv != CKR_OK) {
  3325. PORT_Free(signature);
  3326. return crv;
  3327. }
  3328. crv = NSC_Verify(hSession,
  3329. known_digest,
  3330. PAIRWISE_DIGEST_LENGTH,
  3331. signature,
  3332. signature_length);
  3333. /* Free signature data. */
  3334. PORT_Free(signature);
  3335. if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
  3336. (crv == CKR_SIGNATURE_INVALID)) {
  3337. return CKR_GENERAL_ERROR;
  3338. }
  3339. if (crv != CKR_OK) {
  3340. return crv;
  3341. }
  3342. }
  3343. /**********************************************/
  3344. /* Pairwise Consistency Check for Derivation */
  3345. /**********************************************/
  3346. isDerivable = sftk_isTrue(privateKey, CKA_DERIVE);
  3347. if (isDerivable) {
  3348. /*
  3349. * We are not doing consistency check for Diffie-Hellman Key -
  3350. * otherwise it would be here
  3351. * This is also true for Elliptic Curve Diffie-Hellman keys
  3352. * NOTE: EC keys are currently subjected to pairwise
  3353. * consistency check for signing/verification.
  3354. */
  3355. /*
  3356. * FIPS 140-2 had the following pairwise consistency test for
  3357. * public and private keys used for key agreement:
  3358. * If the keys are used to perform key agreement, then the
  3359. * cryptographic module shall create a second, compatible
  3360. * key pair. The cryptographic module shall perform both
  3361. * sides of the key agreement algorithm and shall compare
  3362. * the resulting shared values. If the shared values are
  3363. * not equal, the test shall fail.
  3364. * This test was removed in Change Notice 3.
  3365. */
  3366. }
  3367. return CKR_OK;
  3368. }
  3369. /* NSC_GenerateKeyPair generates a public-key/private-key pair,
  3370. * creating new key objects. */
  3371. CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
  3372. CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
  3373. CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
  3374. CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
  3375. CK_OBJECT_HANDLE_PTR phPrivateKey)
  3376. {
  3377. SFTKObject * publicKey,*privateKey;
  3378. SFTKSession * session;
  3379. CK_KEY_TYPE key_type;
  3380. CK_RV crv = CKR_OK;
  3381. CK_BBOOL cktrue = CK_TRUE;
  3382. SECStatus rv;
  3383. CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
  3384. CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
  3385. int i;
  3386. SFTKSlot * slot = sftk_SlotFromSessionHandle(hSession);
  3387. unsigned int bitSize;
  3388. /* RSA */
  3389. int public_modulus_bits = 0;
  3390. SECItem pubExp;
  3391. RSAPrivateKey * rsaPriv;
  3392. /* DSA */
  3393. PQGParams pqgParam;
  3394. DHParams dhParam;
  3395. DSAPrivateKey * dsaPriv;
  3396. /* Diffie Hellman */
  3397. int private_value_bits = 0;
  3398. DHPrivateKey * dhPriv;
  3399. #ifdef NSS_ENABLE_ECC
  3400. /* Elliptic Curve Cryptography */
  3401. SECItem ecEncodedParams; /* DER Encoded parameters */
  3402. ECPrivateKey * ecPriv;
  3403. ECParams * ecParams;
  3404. #endif /* NSS_ENABLE_ECC */
  3405. CHECK_FORK();
  3406. if (!slot) {
  3407. return CKR_SESSION_HANDLE_INVALID;
  3408. }
  3409. /*
  3410. * now lets create an object to hang the attributes off of
  3411. */
  3412. publicKey = sftk_NewObject(slot); /* fill in the handle later */
  3413. if (publicKey == NULL) {
  3414. return CKR_HOST_MEMORY;
  3415. }
  3416. /*
  3417. * load the template values into the publicKey
  3418. */
  3419. for (i=0; i < (int) ulPublicKeyAttributeCount; i++) {
  3420. if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS) {
  3421. public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue;
  3422. continue;
  3423. }
  3424. crv = sftk_AddAttributeType(publicKey,
  3425. sftk_attr_expand(&pPublicKeyTemplate[i]));
  3426. if (crv != CKR_OK) break;
  3427. }
  3428. if (crv != CKR_OK) {
  3429. sftk_FreeObject(publicKey);
  3430. return CKR_HOST_MEMORY;
  3431. }
  3432. privateKey = sftk_NewObject(slot); /* fill in the handle later */
  3433. if (privateKey == NULL) {
  3434. sftk_FreeObject(publicKey);
  3435. return CKR_HOST_MEMORY;
  3436. }
  3437. /*
  3438. * now load the private key template
  3439. */
  3440. for (i=0; i < (int) ulPrivateKeyAttributeCount; i++) {
  3441. if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) {
  3442. private_value_bits = *(CK_ULONG *)pPrivateKeyTemplate[i].pValue;
  3443. continue;
  3444. }
  3445. crv = sftk_AddAttributeType(privateKey,
  3446. sftk_attr_expand(&pPrivateKeyTemplate[i]));
  3447. if (crv != CKR_OK) break;
  3448. }
  3449. if (crv != CKR_OK) {
  3450. sftk_FreeObject(publicKey);
  3451. sftk_FreeObject(privateKey);
  3452. return CKR_HOST_MEMORY;
  3453. }
  3454. sftk_DeleteAttributeType(privateKey,CKA_CLASS);
  3455. sftk_DeleteAttributeType(privateKey,CKA_KEY_TYPE);
  3456. sftk_DeleteAttributeType(privateKey,CKA_VALUE);
  3457. sftk_DeleteAttributeType(publicKey,CKA_CLASS);
  3458. sftk_DeleteAttributeType(publicKey,CKA_KEY_TYPE);
  3459. sftk_DeleteAttributeType(publicKey,CKA_VALUE);
  3460. /* Now Set up the parameters to generate the key (based on mechanism) */
  3461. switch (pMechanism->mechanism) {
  3462. case CKM_RSA_PKCS_KEY_PAIR_GEN:
  3463. /* format the keys */
  3464. sftk_DeleteAttributeType(publicKey,CKA_MODULUS);
  3465. sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
  3466. sftk_DeleteAttributeType(privateKey,CKA_MODULUS);
  3467. sftk_DeleteAttributeType(privateKey,CKA_PRIVATE_EXPONENT);
  3468. sftk_DeleteAttributeType(privateKey,CKA_PUBLIC_EXPONENT);
  3469. sftk_DeleteAttributeType(privateKey,CKA_PRIME_1);
  3470. sftk_DeleteAttributeType(privateKey,CKA_PRIME_2);
  3471. sftk_DeleteAttributeType(privateKey,CKA_EXPONENT_1);
  3472. sftk_DeleteAttributeType(privateKey,CKA_EXPONENT_2);
  3473. sftk_DeleteAttributeType(privateKey,CKA_COEFFICIENT);
  3474. key_type = CKK_RSA;
  3475. if (public_modulus_bits == 0) {
  3476. crv = CKR_TEMPLATE_INCOMPLETE;
  3477. break;
  3478. }
  3479. if (public_modulus_bits < RSA_MIN_MODULUS_BITS) {
  3480. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  3481. break;
  3482. }
  3483. if (public_modulus_bits % 2 != 0) {
  3484. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  3485. break;
  3486. }
  3487. /* extract the exponent */
  3488. crv=sftk_Attribute2SSecItem(NULL,&pubExp,publicKey,CKA_PUBLIC_EXPONENT);
  3489. if (crv != CKR_OK) break;
  3490. bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len);
  3491. if (bitSize < 2) {
  3492. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  3493. break;
  3494. }
  3495. crv = sftk_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT,
  3496. sftk_item_expand(&pubExp));
  3497. if (crv != CKR_OK) {
  3498. PORT_Free(pubExp.data);
  3499. break;
  3500. }
  3501. rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp);
  3502. PORT_Free(pubExp.data);
  3503. if (rsaPriv == NULL) {
  3504. if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
  3505. sftk_fatalError = PR_TRUE;
  3506. }
  3507. crv = sftk_MapCryptError(PORT_GetError());
  3508. break;
  3509. }
  3510. /* now fill in the RSA dependent paramenters in the public key */
  3511. crv = sftk_AddAttributeType(publicKey,CKA_MODULUS,
  3512. sftk_item_expand(&rsaPriv->modulus));
  3513. if (crv != CKR_OK) goto kpg_done;
  3514. /* now fill in the RSA dependent paramenters in the private key */
  3515. crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
  3516. sftk_item_expand(&rsaPriv->modulus));
  3517. if (crv != CKR_OK) goto kpg_done;
  3518. crv = sftk_AddAttributeType(privateKey,CKA_MODULUS,
  3519. sftk_item_expand(&rsaPriv->modulus));
  3520. if (crv != CKR_OK) goto kpg_done;
  3521. crv = sftk_AddAttributeType(privateKey,CKA_PRIVATE_EXPONENT,
  3522. sftk_item_expand(&rsaPriv->privateExponent));
  3523. if (crv != CKR_OK) goto kpg_done;
  3524. crv = sftk_AddAttributeType(privateKey,CKA_PRIME_1,
  3525. sftk_item_expand(&rsaPriv->prime1));
  3526. if (crv != CKR_OK) goto kpg_done;
  3527. crv = sftk_AddAttributeType(privateKey,CKA_PRIME_2,
  3528. sftk_item_expand(&rsaPriv->prime2));
  3529. if (crv != CKR_OK) goto kpg_done;
  3530. crv = sftk_AddAttributeType(privateKey,CKA_EXPONENT_1,
  3531. sftk_item_expand(&rsaPriv->exponent1));
  3532. if (crv != CKR_OK) goto kpg_done;
  3533. crv = sftk_AddAttributeType(privateKey,CKA_EXPONENT_2,
  3534. sftk_item_expand(&rsaPriv->exponent2));
  3535. if (crv != CKR_OK) goto kpg_done;
  3536. crv = sftk_AddAttributeType(privateKey,CKA_COEFFICIENT,
  3537. sftk_item_expand(&rsaPriv->coefficient));
  3538. kpg_done:
  3539. /* Should zeroize the contents first, since this func doesn't. */
  3540. PORT_FreeArena(rsaPriv->arena, PR_TRUE);
  3541. break;
  3542. case CKM_DSA_KEY_PAIR_GEN:
  3543. sftk_DeleteAttributeType(publicKey,CKA_VALUE);
  3544. sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
  3545. sftk_DeleteAttributeType(privateKey,CKA_PRIME);
  3546. sftk_DeleteAttributeType(privateKey,CKA_SUBPRIME);
  3547. sftk_DeleteAttributeType(privateKey,CKA_BASE);
  3548. key_type = CKK_DSA;
  3549. /* extract the necessary parameters and copy them to the private key */
  3550. crv=sftk_Attribute2SSecItem(NULL,&pqgParam.prime,publicKey,CKA_PRIME);
  3551. if (crv != CKR_OK) break;
  3552. crv=sftk_Attribute2SSecItem(NULL,&pqgParam.subPrime,publicKey,
  3553. CKA_SUBPRIME);
  3554. if (crv != CKR_OK) {
  3555. PORT_Free(pqgParam.prime.data);
  3556. break;
  3557. }
  3558. crv=sftk_Attribute2SSecItem(NULL,&pqgParam.base,publicKey,CKA_BASE);
  3559. if (crv != CKR_OK) {
  3560. PORT_Free(pqgParam.prime.data);
  3561. PORT_Free(pqgParam.subPrime.data);
  3562. break;
  3563. }
  3564. crv = sftk_AddAttributeType(privateKey,CKA_PRIME,
  3565. sftk_item_expand(&pqgParam.prime));
  3566. if (crv != CKR_OK) {
  3567. PORT_Free(pqgParam.prime.data);
  3568. PORT_Free(pqgParam.subPrime.data);
  3569. PORT_Free(pqgParam.base.data);
  3570. break;
  3571. }
  3572. crv = sftk_AddAttributeType(privateKey,CKA_SUBPRIME,
  3573. sftk_item_expand(&pqgParam.subPrime));
  3574. if (crv != CKR_OK) {
  3575. PORT_Free(pqgParam.prime.data);
  3576. PORT_Free(pqgParam.subPrime.data);
  3577. PORT_Free(pqgParam.base.data);
  3578. break;
  3579. }
  3580. crv = sftk_AddAttributeType(privateKey,CKA_BASE,
  3581. sftk_item_expand(&pqgParam.base));
  3582. if (crv != CKR_OK) {
  3583. PORT_Free(pqgParam.prime.data);
  3584. PORT_Free(pqgParam.subPrime.data);
  3585. PORT_Free(pqgParam.base.data);
  3586. break;
  3587. }
  3588. bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data,
  3589. pqgParam.subPrime.len);
  3590. if (bitSize != DSA_Q_BITS) {
  3591. crv = CKR_TEMPLATE_INCOMPLETE;
  3592. PORT_Free(pqgParam.prime.data);
  3593. PORT_Free(pqgParam.subPrime.data);
  3594. PORT_Free(pqgParam.base.data);
  3595. break;
  3596. }
  3597. bitSize = sftk_GetLengthInBits(pqgParam.prime.data,pqgParam.prime.len);
  3598. if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) {
  3599. crv = CKR_TEMPLATE_INCOMPLETE;
  3600. PORT_Free(pqgParam.prime.data);
  3601. PORT_Free(pqgParam.subPrime.data);
  3602. PORT_Free(pqgParam.base.data);
  3603. break;
  3604. }
  3605. bitSize = sftk_GetLengthInBits(pqgParam.base.data,pqgParam.base.len);
  3606. if ((bitSize < 1) || (bitSize > DSA_MAX_P_BITS)) {
  3607. crv = CKR_TEMPLATE_INCOMPLETE;
  3608. PORT_Free(pqgParam.prime.data);
  3609. PORT_Free(pqgParam.subPrime.data);
  3610. PORT_Free(pqgParam.base.data);
  3611. break;
  3612. }
  3613. /* Generate the key */
  3614. rv = DSA_NewKey(&pqgParam, &dsaPriv);
  3615. PORT_Free(pqgParam.prime.data);
  3616. PORT_Free(pqgParam.subPrime.data);
  3617. PORT_Free(pqgParam.base.data);
  3618. if (rv != SECSuccess) {
  3619. if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
  3620. sftk_fatalError = PR_TRUE;
  3621. }
  3622. crv = sftk_MapCryptError(PORT_GetError());
  3623. break;
  3624. }
  3625. /* store the generated key into the attributes */
  3626. crv = sftk_AddAttributeType(publicKey,CKA_VALUE,
  3627. sftk_item_expand(&dsaPriv->publicValue));
  3628. if (crv != CKR_OK) goto dsagn_done;
  3629. /* now fill in the RSA dependent paramenters in the private key */
  3630. crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
  3631. sftk_item_expand(&dsaPriv->publicValue));
  3632. if (crv != CKR_OK) goto dsagn_done;
  3633. crv = sftk_AddAttributeType(privateKey,CKA_VALUE,
  3634. sftk_item_expand(&dsaPriv->privateValue));
  3635. dsagn_done:
  3636. /* should zeroize, since this function doesn't. */
  3637. PORT_FreeArena(dsaPriv->params.arena, PR_TRUE);
  3638. break;
  3639. case CKM_DH_PKCS_KEY_PAIR_GEN:
  3640. sftk_DeleteAttributeType(privateKey,CKA_PRIME);
  3641. sftk_DeleteAttributeType(privateKey,CKA_BASE);
  3642. sftk_DeleteAttributeType(privateKey,CKA_VALUE);
  3643. sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
  3644. key_type = CKK_DH;
  3645. /* extract the necessary parameters and copy them to private keys */
  3646. crv = sftk_Attribute2SSecItem(NULL, &dhParam.prime, publicKey,
  3647. CKA_PRIME);
  3648. if (crv != CKR_OK) break;
  3649. crv = sftk_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE);
  3650. if (crv != CKR_OK) {
  3651. PORT_Free(dhParam.prime.data);
  3652. break;
  3653. }
  3654. crv = sftk_AddAttributeType(privateKey, CKA_PRIME,
  3655. sftk_item_expand(&dhParam.prime));
  3656. if (crv != CKR_OK) {
  3657. PORT_Free(dhParam.prime.data);
  3658. PORT_Free(dhParam.base.data);
  3659. break;
  3660. }
  3661. crv = sftk_AddAttributeType(privateKey, CKA_BASE,
  3662. sftk_item_expand(&dhParam.base));
  3663. if (crv != CKR_OK) {
  3664. PORT_Free(dhParam.prime.data);
  3665. PORT_Free(dhParam.base.data);
  3666. break;
  3667. }
  3668. bitSize = sftk_GetLengthInBits(dhParam.prime.data,dhParam.prime.len);
  3669. if ((bitSize < DH_MIN_P_BITS) || (bitSize > DH_MAX_P_BITS)) {
  3670. crv = CKR_TEMPLATE_INCOMPLETE;
  3671. PORT_Free(dhParam.prime.data);
  3672. PORT_Free(dhParam.base.data);
  3673. break;
  3674. }
  3675. bitSize = sftk_GetLengthInBits(dhParam.base.data,dhParam.base.len);
  3676. if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS)) {
  3677. crv = CKR_TEMPLATE_INCOMPLETE;
  3678. PORT_Free(dhParam.prime.data);
  3679. PORT_Free(dhParam.base.data);
  3680. break;
  3681. }
  3682. rv = DH_NewKey(&dhParam, &dhPriv);
  3683. PORT_Free(dhParam.prime.data);
  3684. PORT_Free(dhParam.base.data);
  3685. if (rv != SECSuccess) {
  3686. if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
  3687. sftk_fatalError = PR_TRUE;
  3688. }
  3689. crv = sftk_MapCryptError(PORT_GetError());
  3690. break;
  3691. }
  3692. crv=sftk_AddAttributeType(publicKey, CKA_VALUE,
  3693. sftk_item_expand(&dhPriv->publicValue));
  3694. if (crv != CKR_OK) goto dhgn_done;
  3695. crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
  3696. sftk_item_expand(&dhPriv->publicValue));
  3697. if (crv != CKR_OK) goto dhgn_done;
  3698. crv=sftk_AddAttributeType(privateKey, CKA_VALUE,
  3699. sftk_item_expand(&dhPriv->privateValue));
  3700. dhgn_done:
  3701. /* should zeroize, since this function doesn't. */
  3702. PORT_FreeArena(dhPriv->arena, PR_TRUE);
  3703. break;
  3704. #ifdef NSS_ENABLE_ECC
  3705. case CKM_EC_KEY_PAIR_GEN:
  3706. sftk_DeleteAttributeType(privateKey,CKA_EC_PARAMS);
  3707. sftk_DeleteAttributeType(privateKey,CKA_VALUE);
  3708. sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
  3709. key_type = CKK_EC;
  3710. /* extract the necessary parameters and copy them to private keys */
  3711. crv = sftk_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey,
  3712. CKA_EC_PARAMS);
  3713. if (crv != CKR_OK) break;
  3714. crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS,
  3715. sftk_item_expand(&ecEncodedParams));
  3716. if (crv != CKR_OK) {
  3717. PORT_Free(ecEncodedParams.data);
  3718. break;
  3719. }
  3720. /* Decode ec params before calling EC_NewKey */
  3721. rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
  3722. PORT_Free(ecEncodedParams.data);
  3723. if (rv != SECSuccess) {
  3724. crv = sftk_MapCryptError(PORT_GetError());
  3725. break;
  3726. }
  3727. rv = EC_NewKey(ecParams, &ecPriv);
  3728. PORT_FreeArena(ecParams->arena, PR_TRUE);
  3729. if (rv != SECSuccess) {
  3730. if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
  3731. sftk_fatalError = PR_TRUE;
  3732. }
  3733. crv = sftk_MapCryptError(PORT_GetError());
  3734. break;
  3735. }
  3736. if (getenv("NSS_USE_DECODED_CKA_EC_POINT")) {
  3737. crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
  3738. sftk_item_expand(&ecPriv->publicValue));
  3739. } else {
  3740. SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
  3741. &ecPriv->publicValue,
  3742. SEC_ASN1_GET(SEC_OctetStringTemplate));
  3743. if (!pubValue) {
  3744. crv = CKR_ARGUMENTS_BAD;
  3745. goto ecgn_done;
  3746. }
  3747. crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
  3748. sftk_item_expand(pubValue));
  3749. SECITEM_FreeItem(pubValue, PR_TRUE);
  3750. }
  3751. if (crv != CKR_OK) goto ecgn_done;
  3752. crv = sftk_AddAttributeType(privateKey, CKA_VALUE,
  3753. sftk_item_expand(&ecPriv->privateValue));
  3754. if (crv != CKR_OK) goto ecgn_done;
  3755. crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
  3756. sftk_item_expand(&ecPriv->publicValue));
  3757. ecgn_done:
  3758. /* should zeroize, since this function doesn't. */
  3759. PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE);
  3760. break;
  3761. #endif /* NSS_ENABLE_ECC */
  3762. default:
  3763. crv = CKR_MECHANISM_INVALID;
  3764. }
  3765. if (crv != CKR_OK) {
  3766. sftk_FreeObject(privateKey);
  3767. sftk_FreeObject(publicKey);
  3768. return crv;
  3769. }
  3770. /* Add the class, key_type The loop lets us check errors blow out
  3771. * on errors and clean up at the bottom */
  3772. session = NULL; /* make pedtantic happy... session cannot leave the*/
  3773. /* loop below NULL unless an error is set... */
  3774. do {
  3775. crv = sftk_AddAttributeType(privateKey,CKA_CLASS,&privClass,
  3776. sizeof(CK_OBJECT_CLASS));
  3777. if (crv != CKR_OK) break;
  3778. crv = sftk_AddAttributeType(publicKey,CKA_CLASS,&pubClass,
  3779. sizeof(CK_OBJECT_CLASS));
  3780. if (crv != CKR_OK) break;
  3781. crv = sftk_AddAttributeType(privateKey,CKA_KEY_TYPE,&key_type,
  3782. sizeof(CK_KEY_TYPE));
  3783. if (crv != CKR_OK) break;
  3784. crv = sftk_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type,
  3785. sizeof(CK_KEY_TYPE));
  3786. if (crv != CKR_OK) break;
  3787. session = sftk_SessionFromHandle(hSession);
  3788. if (session == NULL) crv = CKR_SESSION_HANDLE_INVALID;
  3789. } while (0);
  3790. if (crv != CKR_OK) {
  3791. sftk_FreeObject(privateKey);
  3792. sftk_FreeObject(publicKey);
  3793. return crv;
  3794. }
  3795. /*
  3796. * handle the base object cleanup for the public Key
  3797. */
  3798. crv = sftk_handleObject(privateKey,session);
  3799. if (crv != CKR_OK) {
  3800. sftk_FreeSession(session);
  3801. sftk_FreeObject(privateKey);
  3802. sftk_FreeObject(publicKey);
  3803. return crv;
  3804. }
  3805. /*
  3806. * handle the base object cleanup for the private Key
  3807. * If we have any problems, we destroy the public Key we've
  3808. * created and linked.
  3809. */
  3810. crv = sftk_handleObject(publicKey,session);
  3811. sftk_FreeSession(session);
  3812. if (crv != CKR_OK) {
  3813. sftk_FreeObject(publicKey);
  3814. NSC_DestroyObject(hSession,privateKey->handle);
  3815. sftk_FreeObject(privateKey);
  3816. return crv;
  3817. }
  3818. if (sftk_isTrue(privateKey,CKA_SENSITIVE)) {
  3819. sftk_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE,
  3820. &cktrue,sizeof(CK_BBOOL));
  3821. }
  3822. if (sftk_isTrue(publicKey,CKA_SENSITIVE)) {
  3823. sftk_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE,
  3824. &cktrue,sizeof(CK_BBOOL));
  3825. }
  3826. if (!sftk_isTrue(privateKey,CKA_EXTRACTABLE)) {
  3827. sftk_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE,
  3828. &cktrue,sizeof(CK_BBOOL));
  3829. }
  3830. if (!sftk_isTrue(publicKey,CKA_EXTRACTABLE)) {
  3831. sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
  3832. &cktrue,sizeof(CK_BBOOL));
  3833. }
  3834. /* Perform FIPS 140-2 pairwise consistency check. */
  3835. crv = sftk_PairwiseConsistencyCheck(hSession,
  3836. publicKey, privateKey, key_type);
  3837. if (crv != CKR_OK) {
  3838. NSC_DestroyObject(hSession,publicKey->handle);
  3839. sftk_FreeObject(publicKey);
  3840. NSC_DestroyObject(hSession,privateKey->handle);
  3841. sftk_FreeObject(privateKey);
  3842. if (sftk_audit_enabled) {
  3843. char msg[128];
  3844. PR_snprintf(msg,sizeof msg,
  3845. "C_GenerateKeyPair(hSession=0x%08lX, "
  3846. "pMechanism->mechanism=0x%08lX)=0x%08lX "
  3847. "self-test: pair-wise consistency test failed",
  3848. (PRUint32)hSession,(PRUint32)pMechanism->mechanism,
  3849. (PRUint32)crv);
  3850. sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
  3851. }
  3852. return crv;
  3853. }
  3854. *phPrivateKey = privateKey->handle;
  3855. *phPublicKey = publicKey->handle;
  3856. sftk_FreeObject(publicKey);
  3857. sftk_FreeObject(privateKey);
  3858. return CKR_OK;
  3859. }
  3860. static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
  3861. {
  3862. NSSLOWKEYPrivateKey *lk = NULL;
  3863. NSSLOWKEYPrivateKeyInfo *pki = NULL;
  3864. SFTKAttribute *attribute = NULL;
  3865. PLArenaPool *arena = NULL;
  3866. SECOidTag algorithm = SEC_OID_UNKNOWN;
  3867. void *dummy, *param = NULL;
  3868. SECStatus rv = SECSuccess;
  3869. SECItem *encodedKey = NULL;
  3870. #ifdef NSS_ENABLE_ECC
  3871. SECItem *fordebug;
  3872. int savelen;
  3873. #endif
  3874. if(!key) {
  3875. *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */
  3876. return NULL;
  3877. }
  3878. attribute = sftk_FindAttribute(key, CKA_KEY_TYPE);
  3879. if(!attribute) {
  3880. *crvp = CKR_KEY_TYPE_INCONSISTENT;
  3881. return NULL;
  3882. }
  3883. lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp);
  3884. sftk_FreeAttribute(attribute);
  3885. if(!lk) {
  3886. return NULL;
  3887. }
  3888. arena = PORT_NewArena(2048); /* XXX different size? */
  3889. if(!arena) {
  3890. *crvp = CKR_HOST_MEMORY;
  3891. rv = SECFailure;
  3892. goto loser;
  3893. }
  3894. pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
  3895. sizeof(NSSLOWKEYPrivateKeyInfo));
  3896. if(!pki) {
  3897. *crvp = CKR_HOST_MEMORY;
  3898. rv = SECFailure;
  3899. goto loser;
  3900. }
  3901. pki->arena = arena;
  3902. param = NULL;
  3903. switch(lk->keyType) {
  3904. case NSSLOWKEYRSAKey:
  3905. prepare_low_rsa_priv_key_for_asn1(lk);
  3906. dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
  3907. nsslowkey_RSAPrivateKeyTemplate);
  3908. algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
  3909. break;
  3910. case NSSLOWKEYDSAKey:
  3911. prepare_low_dsa_priv_key_export_for_asn1(lk);
  3912. dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
  3913. nsslowkey_DSAPrivateKeyExportTemplate);
  3914. prepare_low_pqg_params_for_asn1(&lk->u.dsa.params);
  3915. param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
  3916. nsslowkey_PQGParamsTemplate);
  3917. algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
  3918. break;
  3919. #ifdef NSS_ENABLE_ECC
  3920. case NSSLOWKEYECKey:
  3921. prepare_low_ec_priv_key_for_asn1(lk);
  3922. /* Public value is encoded as a bit string so adjust length
  3923. * to be in bits before ASN encoding and readjust
  3924. * immediately after.
  3925. *
  3926. * Since the SECG specification recommends not including the
  3927. * parameters as part of ECPrivateKey, we zero out the curveOID
  3928. * length before encoding and restore it later.
  3929. */
  3930. lk->u.ec.publicValue.len <<= 3;
  3931. savelen = lk->u.ec.ecParams.curveOID.len;
  3932. lk->u.ec.ecParams.curveOID.len = 0;
  3933. dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
  3934. nsslowkey_ECPrivateKeyTemplate);
  3935. lk->u.ec.ecParams.curveOID.len = savelen;
  3936. lk->u.ec.publicValue.len >>= 3;
  3937. fordebug = &pki->privateKey;
  3938. SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
  3939. fordebug);
  3940. param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding);
  3941. algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
  3942. break;
  3943. #endif /* NSS_ENABLE_ECC */
  3944. case NSSLOWKEYDHKey:
  3945. default:
  3946. dummy = NULL;
  3947. break;
  3948. }
  3949. if(!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) {
  3950. *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
  3951. rv = SECFailure;
  3952. goto loser;
  3953. }
  3954. rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm,
  3955. (SECItem*)param);
  3956. if(rv != SECSuccess) {
  3957. *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
  3958. rv = SECFailure;
  3959. goto loser;
  3960. }
  3961. dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
  3962. NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
  3963. if(!dummy) {
  3964. *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
  3965. rv = SECFailure;
  3966. goto loser;
  3967. }
  3968. encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki,
  3969. nsslowkey_PrivateKeyInfoTemplate);
  3970. *crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR;
  3971. #ifdef NSS_ENABLE_ECC
  3972. fordebug = encodedKey;
  3973. SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType,
  3974. fordebug);
  3975. #endif
  3976. loser:
  3977. if(arena) {
  3978. PORT_FreeArena(arena, PR_TRUE);
  3979. }
  3980. if(lk && (lk != key->objectInfo)) {
  3981. nsslowkey_DestroyPrivateKey(lk);
  3982. }
  3983. if(param) {
  3984. SECITEM_ZfreeItem((SECItem*)param, PR_TRUE);
  3985. }
  3986. if(rv != SECSuccess) {
  3987. return NULL;
  3988. }
  3989. return encodedKey;
  3990. }
  3991. /* it doesn't matter yet, since we colapse error conditions in the
  3992. * level above, but we really should map those few key error differences */
  3993. static CK_RV
  3994. sftk_mapWrap(CK_RV crv)
  3995. {
  3996. switch (crv) {
  3997. case CKR_ENCRYPTED_DATA_INVALID: crv = CKR_WRAPPED_KEY_INVALID; break;
  3998. }
  3999. return crv;
  4000. }
  4001. /* NSC_WrapKey wraps (i.e., encrypts) a key. */
  4002. CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
  4003. CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
  4004. CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
  4005. CK_ULONG_PTR pulWrappedKeyLen)
  4006. {
  4007. SFTKSession *session;
  4008. SFTKAttribute *attribute;
  4009. SFTKObject *key;
  4010. CK_RV crv;
  4011. CHECK_FORK();
  4012. session = sftk_SessionFromHandle(hSession);
  4013. if (session == NULL) {
  4014. return CKR_SESSION_HANDLE_INVALID;
  4015. }
  4016. key = sftk_ObjectFromHandle(hKey,session);
  4017. sftk_FreeSession(session);
  4018. if (key == NULL) {
  4019. return CKR_KEY_HANDLE_INVALID;
  4020. }
  4021. switch(key->objclass) {
  4022. case CKO_SECRET_KEY:
  4023. {
  4024. SFTKSessionContext *context = NULL;
  4025. SECItem pText;
  4026. attribute = sftk_FindAttribute(key,CKA_VALUE);
  4027. if (attribute == NULL) {
  4028. crv = CKR_KEY_TYPE_INCONSISTENT;
  4029. break;
  4030. }
  4031. crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
  4032. CKA_WRAP, CKA_WRAP, SFTK_ENCRYPT, PR_TRUE);
  4033. if (crv != CKR_OK) {
  4034. sftk_FreeAttribute(attribute);
  4035. break;
  4036. }
  4037. pText.type = siBuffer;
  4038. pText.data = (unsigned char *)attribute->attrib.pValue;
  4039. pText.len = attribute->attrib.ulValueLen;
  4040. /* Find out if this is a block cipher. */
  4041. crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_FALSE,NULL);
  4042. if (crv != CKR_OK || !context)
  4043. break;
  4044. if (context->blockSize > 1) {
  4045. unsigned int remainder = pText.len % context->blockSize;
  4046. if (!context->doPad && remainder) {
  4047. /* When wrapping secret keys with unpadded block ciphers,
  4048. ** the keys are zero padded, if necessary, to fill out
  4049. ** a full block.
  4050. */
  4051. pText.len += context->blockSize - remainder;
  4052. pText.data = PORT_ZAlloc(pText.len);
  4053. if (pText.data)
  4054. memcpy(pText.data, attribute->attrib.pValue,
  4055. attribute->attrib.ulValueLen);
  4056. else {
  4057. crv = CKR_HOST_MEMORY;
  4058. break;
  4059. }
  4060. }
  4061. }
  4062. crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data,
  4063. pText.len, pWrappedKey, pulWrappedKeyLen);
  4064. /* always force a finalize, both on errors and when
  4065. * we are just getting the size */
  4066. if (crv != CKR_OK || pWrappedKey == NULL) {
  4067. CK_RV lcrv ;
  4068. lcrv = sftk_GetContext(hSession,&context,
  4069. SFTK_ENCRYPT,PR_FALSE,NULL);
  4070. sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
  4071. if (lcrv == CKR_OK && context) {
  4072. sftk_FreeContext(context);
  4073. }
  4074. }
  4075. if (pText.data != (unsigned char *)attribute->attrib.pValue)
  4076. PORT_ZFree(pText.data, pText.len);
  4077. sftk_FreeAttribute(attribute);
  4078. break;
  4079. }
  4080. case CKO_PRIVATE_KEY:
  4081. {
  4082. SECItem *bpki = sftk_PackagePrivateKey(key, &crv);
  4083. SFTKSessionContext *context = NULL;
  4084. if(!bpki) {
  4085. break;
  4086. }
  4087. crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
  4088. CKA_WRAP, CKA_WRAP, SFTK_ENCRYPT, PR_TRUE);
  4089. if(crv != CKR_OK) {
  4090. SECITEM_ZfreeItem(bpki, PR_TRUE);
  4091. crv = CKR_KEY_TYPE_INCONSISTENT;
  4092. break;
  4093. }
  4094. crv = NSC_Encrypt(hSession, bpki->data, bpki->len,
  4095. pWrappedKey, pulWrappedKeyLen);
  4096. /* always force a finalize */
  4097. if (crv != CKR_OK || pWrappedKey == NULL) {
  4098. CK_RV lcrv ;
  4099. lcrv = sftk_GetContext(hSession,&context,
  4100. SFTK_ENCRYPT,PR_FALSE,NULL);
  4101. sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
  4102. if (lcrv == CKR_OK && context) {
  4103. sftk_FreeContext(context);
  4104. }
  4105. }
  4106. SECITEM_ZfreeItem(bpki, PR_TRUE);
  4107. break;
  4108. }
  4109. default:
  4110. crv = CKR_KEY_TYPE_INCONSISTENT;
  4111. break;
  4112. }
  4113. sftk_FreeObject(key);
  4114. return sftk_mapWrap(crv);
  4115. }
  4116. /*
  4117. * import a pprivate key info into the desired slot
  4118. */
  4119. static SECStatus
  4120. sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
  4121. {
  4122. CK_BBOOL cktrue = CK_TRUE;
  4123. CK_KEY_TYPE keyType = CKK_RSA;
  4124. SECStatus rv = SECFailure;
  4125. const SEC_ASN1Template *keyTemplate, *paramTemplate;
  4126. void *paramDest = NULL;
  4127. PLArenaPool *arena;
  4128. NSSLOWKEYPrivateKey *lpk = NULL;
  4129. NSSLOWKEYPrivateKeyInfo *pki = NULL;
  4130. CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;
  4131. arena = PORT_NewArena(2048);
  4132. if(!arena) {
  4133. return SECFailure;
  4134. }
  4135. pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
  4136. sizeof(NSSLOWKEYPrivateKeyInfo));
  4137. if(!pki) {
  4138. PORT_FreeArena(arena, PR_FALSE);
  4139. return SECFailure;
  4140. }
  4141. if(SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki)
  4142. != SECSuccess) {
  4143. PORT_FreeArena(arena, PR_TRUE);
  4144. return SECFailure;
  4145. }
  4146. lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(arena,
  4147. sizeof(NSSLOWKEYPrivateKey));
  4148. if(lpk == NULL) {
  4149. goto loser;
  4150. }
  4151. lpk->arena = arena;
  4152. switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
  4153. case SEC_OID_PKCS1_RSA_ENCRYPTION:
  4154. keyTemplate = nsslowkey_RSAPrivateKeyTemplate;
  4155. paramTemplate = NULL;
  4156. paramDest = NULL;
  4157. lpk->keyType = NSSLOWKEYRSAKey;
  4158. prepare_low_rsa_priv_key_for_asn1(lpk);
  4159. break;
  4160. case SEC_OID_ANSIX9_DSA_SIGNATURE:
  4161. keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
  4162. paramTemplate = nsslowkey_PQGParamsTemplate;
  4163. paramDest = &(lpk->u.dsa.params);
  4164. lpk->keyType = NSSLOWKEYDSAKey;
  4165. prepare_low_dsa_priv_key_export_for_asn1(lpk);
  4166. prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params);
  4167. break;
  4168. /* case NSSLOWKEYDHKey: */
  4169. #ifdef NSS_ENABLE_ECC
  4170. case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
  4171. keyTemplate = nsslowkey_ECPrivateKeyTemplate;
  4172. paramTemplate = NULL;
  4173. paramDest = &(lpk->u.ec.ecParams.DEREncoding);
  4174. lpk->keyType = NSSLOWKEYECKey;
  4175. prepare_low_ec_priv_key_for_asn1(lpk);
  4176. prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams);
  4177. break;
  4178. #endif /* NSS_ENABLE_ECC */
  4179. default:
  4180. keyTemplate = NULL;
  4181. paramTemplate = NULL;
  4182. paramDest = NULL;
  4183. break;
  4184. }
  4185. if(!keyTemplate) {
  4186. goto loser;
  4187. }
  4188. /* decode the private key and any algorithm parameters */
  4189. rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
  4190. #ifdef NSS_ENABLE_ECC
  4191. if (lpk->keyType == NSSLOWKEYECKey) {
  4192. /* convert length in bits to length in bytes */
  4193. lpk->u.ec.publicValue.len >>= 3;
  4194. rv = SECITEM_CopyItem(arena,
  4195. &(lpk->u.ec.ecParams.DEREncoding),
  4196. &(pki->algorithm.parameters));
  4197. if(rv != SECSuccess) {
  4198. goto loser;
  4199. }
  4200. }
  4201. #endif /* NSS_ENABLE_ECC */
  4202. if(rv != SECSuccess) {
  4203. goto loser;
  4204. }
  4205. if(paramDest && paramTemplate) {
  4206. rv = SEC_QuickDERDecodeItem(arena, paramDest, paramTemplate,
  4207. &(pki->algorithm.parameters));
  4208. if(rv != SECSuccess) {
  4209. goto loser;
  4210. }
  4211. }
  4212. rv = SECFailure;
  4213. switch (lpk->keyType) {
  4214. case NSSLOWKEYRSAKey:
  4215. keyType = CKK_RSA;
  4216. if(sftk_hasAttribute(key, CKA_NETSCAPE_DB)) {
  4217. sftk_DeleteAttributeType(key, CKA_NETSCAPE_DB);
  4218. }
  4219. crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
  4220. sizeof(keyType));
  4221. if(crv != CKR_OK) break;
  4222. crv = sftk_AddAttributeType(key, CKA_UNWRAP, &cktrue,
  4223. sizeof(CK_BBOOL));
  4224. if(crv != CKR_OK) break;
  4225. crv = sftk_AddAttributeType(key, CKA_DECRYPT, &cktrue,
  4226. sizeof(CK_BBOOL));
  4227. if(crv != CKR_OK) break;
  4228. crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
  4229. sizeof(CK_BBOOL));
  4230. if(crv != CKR_OK) break;
  4231. crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
  4232. sizeof(CK_BBOOL));
  4233. if(crv != CKR_OK) break;
  4234. crv = sftk_AddAttributeType(key, CKA_MODULUS,
  4235. sftk_item_expand(&lpk->u.rsa.modulus));
  4236. if(crv != CKR_OK) break;
  4237. crv = sftk_AddAttributeType(key, CKA_PUBLIC_EXPONENT,
  4238. sftk_item_expand(&lpk->u.rsa.publicExponent));
  4239. if(crv != CKR_OK) break;
  4240. crv = sftk_AddAttributeType(key, CKA_PRIVATE_EXPONENT,
  4241. sftk_item_expand(&lpk->u.rsa.privateExponent));
  4242. if(crv != CKR_OK) break;
  4243. crv = sftk_AddAttributeType(key, CKA_PRIME_1,
  4244. sftk_item_expand(&lpk->u.rsa.prime1));
  4245. if(crv != CKR_OK) break;
  4246. crv = sftk_AddAttributeType(key, CKA_PRIME_2,
  4247. sftk_item_expand(&lpk->u.rsa.prime2));
  4248. if(crv != CKR_OK) break;
  4249. crv = sftk_AddAttributeType(key, CKA_EXPONENT_1,
  4250. sftk_item_expand(&lpk->u.rsa.exponent1));
  4251. if(crv != CKR_OK) break;
  4252. crv = sftk_AddAttributeType(key, CKA_EXPONENT_2,
  4253. sftk_item_expand(&lpk->u.rsa.exponent2));
  4254. if(crv != CKR_OK) break;
  4255. crv = sftk_AddAttributeType(key, CKA_COEFFICIENT,
  4256. sftk_item_expand(&lpk->u.rsa.coefficient));
  4257. break;
  4258. case NSSLOWKEYDSAKey:
  4259. keyType = CKK_DSA;
  4260. crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK :
  4261. CKR_KEY_TYPE_INCONSISTENT;
  4262. if(crv != CKR_OK) break;
  4263. crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
  4264. sizeof(keyType));
  4265. if(crv != CKR_OK) break;
  4266. crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
  4267. sizeof(CK_BBOOL));
  4268. if(crv != CKR_OK) break;
  4269. crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
  4270. sizeof(CK_BBOOL));
  4271. if(crv != CKR_OK) break;
  4272. crv = sftk_AddAttributeType(key, CKA_PRIME,
  4273. sftk_item_expand(&lpk->u.dsa.params.prime));
  4274. if(crv != CKR_OK) break;
  4275. crv = sftk_AddAttributeType(key, CKA_SUBPRIME,
  4276. sftk_item_expand(&lpk->u.dsa.params.subPrime));
  4277. if(crv != CKR_OK) break;
  4278. crv = sftk_AddAttributeType(key, CKA_BASE,
  4279. sftk_item_expand(&lpk->u.dsa.params.base));
  4280. if(crv != CKR_OK) break;
  4281. crv = sftk_AddAttributeType(key, CKA_VALUE,
  4282. sftk_item_expand(&lpk->u.dsa.privateValue));
  4283. if(crv != CKR_OK) break;
  4284. break;
  4285. #ifdef notdef
  4286. case NSSLOWKEYDHKey:
  4287. template = dhTemplate;
  4288. templateCount = sizeof(dhTemplate)/sizeof(CK_ATTRIBUTE);
  4289. keyType = CKK_DH;
  4290. break;
  4291. #endif
  4292. /* what about fortezza??? */
  4293. #ifdef NSS_ENABLE_ECC
  4294. case NSSLOWKEYECKey:
  4295. keyType = CKK_EC;
  4296. crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK :
  4297. CKR_KEY_TYPE_INCONSISTENT;
  4298. if(crv != CKR_OK) break;
  4299. crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
  4300. sizeof(keyType));
  4301. if(crv != CKR_OK) break;
  4302. crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
  4303. sizeof(CK_BBOOL));
  4304. if(crv != CKR_OK) break;
  4305. crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
  4306. sizeof(CK_BBOOL));
  4307. if(crv != CKR_OK) break;
  4308. crv = sftk_AddAttributeType(key, CKA_DERIVE, &cktrue,
  4309. sizeof(CK_BBOOL));
  4310. if(crv != CKR_OK) break;
  4311. crv = sftk_AddAttributeType(key, CKA_EC_PARAMS,
  4312. sftk_item_expand(&lpk->u.ec.ecParams.DEREncoding));
  4313. if(crv != CKR_OK) break;
  4314. crv = sftk_AddAttributeType(key, CKA_VALUE,
  4315. sftk_item_expand(&lpk->u.ec.privateValue));
  4316. if(crv != CKR_OK) break;
  4317. /* XXX Do we need to decode the EC Params here ?? */
  4318. break;
  4319. #endif /* NSS_ENABLE_ECC */
  4320. default:
  4321. crv = CKR_KEY_TYPE_INCONSISTENT;
  4322. break;
  4323. }
  4324. loser:
  4325. if(lpk) {
  4326. nsslowkey_DestroyPrivateKey(lpk);
  4327. }
  4328. if(crv != CKR_OK) {
  4329. return SECFailure;
  4330. }
  4331. return SECSuccess;
  4332. }
  4333. /* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
  4334. CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
  4335. CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
  4336. CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
  4337. CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
  4338. CK_OBJECT_HANDLE_PTR phKey)
  4339. {
  4340. SFTKObject *key = NULL;
  4341. SFTKSession *session;
  4342. CK_ULONG key_length = 0;
  4343. unsigned char * buf = NULL;
  4344. CK_RV crv = CKR_OK;
  4345. int i;
  4346. CK_ULONG bsize = ulWrappedKeyLen;
  4347. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  4348. SECItem bpki;
  4349. CK_OBJECT_CLASS target_type = CKO_SECRET_KEY;
  4350. CHECK_FORK();
  4351. if (!slot) {
  4352. return CKR_SESSION_HANDLE_INVALID;
  4353. }
  4354. /*
  4355. * now lets create an object to hang the attributes off of
  4356. */
  4357. key = sftk_NewObject(slot); /* fill in the handle later */
  4358. if (key == NULL) {
  4359. return CKR_HOST_MEMORY;
  4360. }
  4361. /*
  4362. * load the template values into the object
  4363. */
  4364. for (i=0; i < (int) ulAttributeCount; i++) {
  4365. if (pTemplate[i].type == CKA_VALUE_LEN) {
  4366. key_length = *(CK_ULONG *)pTemplate[i].pValue;
  4367. continue;
  4368. }
  4369. if (pTemplate[i].type == CKA_CLASS) {
  4370. target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
  4371. }
  4372. crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
  4373. if (crv != CKR_OK) break;
  4374. }
  4375. if (crv != CKR_OK) {
  4376. sftk_FreeObject(key);
  4377. return crv;
  4378. }
  4379. crv = sftk_CryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
  4380. CKA_UNWRAP, SFTK_DECRYPT, PR_FALSE);
  4381. if (crv != CKR_OK) {
  4382. sftk_FreeObject(key);
  4383. return sftk_mapWrap(crv);
  4384. }
  4385. /* allocate the buffer to decrypt into
  4386. * this assumes the unwrapped key is never larger than the
  4387. * wrapped key. For all the mechanisms we support this is true */
  4388. buf = (unsigned char *)PORT_Alloc( ulWrappedKeyLen);
  4389. bsize = ulWrappedKeyLen;
  4390. crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize);
  4391. if (crv != CKR_OK) {
  4392. sftk_FreeObject(key);
  4393. PORT_Free(buf);
  4394. return sftk_mapWrap(crv);
  4395. }
  4396. switch(target_type) {
  4397. case CKO_SECRET_KEY:
  4398. if (!sftk_hasAttribute(key,CKA_KEY_TYPE)) {
  4399. crv = CKR_TEMPLATE_INCOMPLETE;
  4400. break;
  4401. }
  4402. if (key_length == 0 || key_length > bsize) {
  4403. key_length = bsize;
  4404. }
  4405. if (key_length > MAX_KEY_LEN) {
  4406. crv = CKR_TEMPLATE_INCONSISTENT;
  4407. break;
  4408. }
  4409. /* add the value */
  4410. crv = sftk_AddAttributeType(key,CKA_VALUE,buf,key_length);
  4411. break;
  4412. case CKO_PRIVATE_KEY:
  4413. bpki.data = (unsigned char *)buf;
  4414. bpki.len = bsize;
  4415. crv = CKR_OK;
  4416. if(sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) {
  4417. crv = CKR_TEMPLATE_INCOMPLETE;
  4418. }
  4419. break;
  4420. default:
  4421. crv = CKR_TEMPLATE_INCONSISTENT;
  4422. break;
  4423. }
  4424. PORT_ZFree(buf, bsize);
  4425. if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
  4426. /* get the session */
  4427. session = sftk_SessionFromHandle(hSession);
  4428. if (session == NULL) {
  4429. sftk_FreeObject(key);
  4430. return CKR_SESSION_HANDLE_INVALID;
  4431. }
  4432. /*
  4433. * handle the base object stuff
  4434. */
  4435. crv = sftk_handleObject(key,session);
  4436. *phKey = key->handle;
  4437. sftk_FreeSession(session);
  4438. sftk_FreeObject(key);
  4439. return crv;
  4440. }
  4441. /*
  4442. * The SSL key gen mechanism create's lots of keys. This function handles the
  4443. * details of each of these key creation.
  4444. */
  4445. static CK_RV
  4446. sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey,
  4447. PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize,
  4448. CK_OBJECT_HANDLE *keyHandle)
  4449. {
  4450. SFTKObject *key;
  4451. SFTKSession *session;
  4452. CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
  4453. CK_BBOOL cktrue = CK_TRUE;
  4454. CK_BBOOL ckfalse = CK_FALSE;
  4455. CK_RV crv = CKR_HOST_MEMORY;
  4456. /*
  4457. * now lets create an object to hang the attributes off of
  4458. */
  4459. *keyHandle = CK_INVALID_HANDLE;
  4460. key = sftk_NewObject(baseKey->slot);
  4461. if (key == NULL) return CKR_HOST_MEMORY;
  4462. sftk_narrowToSessionObject(key)->wasDerived = PR_TRUE;
  4463. crv = sftk_CopyObject(key,baseKey);
  4464. if (crv != CKR_OK) goto loser;
  4465. if (isMacKey) {
  4466. crv = sftk_forceAttribute(key,CKA_KEY_TYPE,&keyType,sizeof(keyType));
  4467. if (crv != CKR_OK) goto loser;
  4468. crv = sftk_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
  4469. if (crv != CKR_OK) goto loser;
  4470. crv = sftk_forceAttribute(key,CKA_ENCRYPT,&ckfalse,sizeof(CK_BBOOL));
  4471. if (crv != CKR_OK) goto loser;
  4472. crv = sftk_forceAttribute(key,CKA_DECRYPT,&ckfalse,sizeof(CK_BBOOL));
  4473. if (crv != CKR_OK) goto loser;
  4474. crv = sftk_forceAttribute(key,CKA_SIGN,&cktrue,sizeof(CK_BBOOL));
  4475. if (crv != CKR_OK) goto loser;
  4476. crv = sftk_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
  4477. if (crv != CKR_OK) goto loser;
  4478. crv = sftk_forceAttribute(key,CKA_WRAP,&ckfalse,sizeof(CK_BBOOL));
  4479. if (crv != CKR_OK) goto loser;
  4480. crv = sftk_forceAttribute(key,CKA_UNWRAP,&ckfalse,sizeof(CK_BBOOL));
  4481. if (crv != CKR_OK) goto loser;
  4482. }
  4483. crv = sftk_forceAttribute(key,CKA_VALUE,keyBlock,keySize);
  4484. if (crv != CKR_OK) goto loser;
  4485. /* get the session */
  4486. crv = CKR_HOST_MEMORY;
  4487. session = sftk_SessionFromHandle(hSession);
  4488. if (session == NULL) { goto loser; }
  4489. crv = sftk_handleObject(key,session);
  4490. sftk_FreeSession(session);
  4491. *keyHandle = key->handle;
  4492. loser:
  4493. if (key) sftk_FreeObject(key);
  4494. return crv;
  4495. }
  4496. /*
  4497. * if there is an error, we need to free the keys we already created in SSL
  4498. * This is the routine that will do it..
  4499. */
  4500. static void
  4501. sftk_freeSSLKeys(CK_SESSION_HANDLE session,
  4502. CK_SSL3_KEY_MAT_OUT *returnedMaterial )
  4503. {
  4504. if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE) {
  4505. NSC_DestroyObject(session,returnedMaterial->hClientMacSecret);
  4506. }
  4507. if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE) {
  4508. NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
  4509. }
  4510. if (returnedMaterial->hClientKey != CK_INVALID_HANDLE) {
  4511. NSC_DestroyObject(session, returnedMaterial->hClientKey);
  4512. }
  4513. if (returnedMaterial->hServerKey != CK_INVALID_HANDLE) {
  4514. NSC_DestroyObject(session, returnedMaterial->hServerKey);
  4515. }
  4516. }
  4517. /*
  4518. * when deriving from sensitive and extractable keys, we need to preserve some
  4519. * of the semantics in the derived key. This helper routine maintains these
  4520. * semantics.
  4521. */
  4522. static CK_RV
  4523. sftk_DeriveSensitiveCheck(SFTKObject *baseKey,SFTKObject *destKey)
  4524. {
  4525. PRBool hasSensitive;
  4526. PRBool sensitive = PR_FALSE;
  4527. PRBool hasExtractable;
  4528. PRBool extractable = PR_TRUE;
  4529. CK_RV crv = CKR_OK;
  4530. SFTKAttribute *att;
  4531. hasSensitive = PR_FALSE;
  4532. att = sftk_FindAttribute(destKey,CKA_SENSITIVE);
  4533. if (att) {
  4534. hasSensitive = PR_TRUE;
  4535. sensitive = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
  4536. sftk_FreeAttribute(att);
  4537. }
  4538. hasExtractable = PR_FALSE;
  4539. att = sftk_FindAttribute(destKey,CKA_EXTRACTABLE);
  4540. if (att) {
  4541. hasExtractable = PR_TRUE;
  4542. extractable = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
  4543. sftk_FreeAttribute(att);
  4544. }
  4545. /* don't make a key more accessible */
  4546. if (sftk_isTrue(baseKey,CKA_SENSITIVE) && hasSensitive &&
  4547. (sensitive == PR_FALSE)) {
  4548. return CKR_KEY_FUNCTION_NOT_PERMITTED;
  4549. }
  4550. if (!sftk_isTrue(baseKey,CKA_EXTRACTABLE) && hasExtractable &&
  4551. (extractable == PR_TRUE)) {
  4552. return CKR_KEY_FUNCTION_NOT_PERMITTED;
  4553. }
  4554. /* inherit parent's sensitivity */
  4555. if (!hasSensitive) {
  4556. att = sftk_FindAttribute(baseKey,CKA_SENSITIVE);
  4557. if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT;
  4558. crv = sftk_defaultAttribute(destKey,sftk_attr_expand(&att->attrib));
  4559. sftk_FreeAttribute(att);
  4560. if (crv != CKR_OK) return crv;
  4561. }
  4562. if (!hasExtractable) {
  4563. att = sftk_FindAttribute(baseKey,CKA_EXTRACTABLE);
  4564. if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT;
  4565. crv = sftk_defaultAttribute(destKey,sftk_attr_expand(&att->attrib));
  4566. sftk_FreeAttribute(att);
  4567. if (crv != CKR_OK) return crv;
  4568. }
  4569. /* we should inherit the parent's always extractable/ never sensitive info,
  4570. * but handleObject always forces this attributes, so we would need to do
  4571. * something special. */
  4572. return CKR_OK;
  4573. }
  4574. /*
  4575. * make known fixed PKCS #11 key types to their sizes in bytes
  4576. */
  4577. unsigned long
  4578. sftk_MapKeySize(CK_KEY_TYPE keyType)
  4579. {
  4580. switch (keyType) {
  4581. case CKK_CDMF:
  4582. return 8;
  4583. case CKK_DES:
  4584. return 8;
  4585. case CKK_DES2:
  4586. return 16;
  4587. case CKK_DES3:
  4588. return 24;
  4589. /* IDEA and CAST need to be added */
  4590. default:
  4591. break;
  4592. }
  4593. return 0;
  4594. }
  4595. /*
  4596. * SSL Key generation given pre master secret
  4597. */
  4598. #define NUM_MIXERS 9
  4599. static const char * const mixers[NUM_MIXERS] = {
  4600. "A",
  4601. "BB",
  4602. "CCC",
  4603. "DDDD",
  4604. "EEEEE",
  4605. "FFFFFF",
  4606. "GGGGGGG",
  4607. "HHHHHHHH",
  4608. "IIIIIIIII" };
  4609. #define SSL3_PMS_LENGTH 48
  4610. #define SSL3_MASTER_SECRET_LENGTH 48
  4611. #define SSL3_RANDOM_LENGTH 32
  4612. /* NSC_DeriveKey derives a key from a base key, creating a new key object. */
  4613. CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
  4614. CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
  4615. CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
  4616. CK_OBJECT_HANDLE_PTR phKey)
  4617. {
  4618. SFTKSession * session;
  4619. SFTKSlot * slot = sftk_SlotFromSessionHandle(hSession);
  4620. SFTKObject * key;
  4621. SFTKObject * sourceKey;
  4622. SFTKAttribute * att = NULL;
  4623. SFTKAttribute * att2 = NULL;
  4624. unsigned char * buf;
  4625. SHA1Context * sha;
  4626. MD5Context * md5;
  4627. MD2Context * md2;
  4628. CK_ULONG macSize;
  4629. CK_ULONG tmpKeySize;
  4630. CK_ULONG IVSize;
  4631. CK_ULONG keySize = 0;
  4632. CK_RV crv = CKR_OK;
  4633. CK_BBOOL cktrue = CK_TRUE;
  4634. CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
  4635. CK_OBJECT_CLASS classType = CKO_SECRET_KEY;
  4636. CK_KEY_DERIVATION_STRING_DATA *stringPtr;
  4637. PRBool isTLS = PR_FALSE;
  4638. PRBool isDH = PR_FALSE;
  4639. SECStatus rv;
  4640. int i;
  4641. unsigned int outLen;
  4642. unsigned char sha_out[SHA1_LENGTH];
  4643. unsigned char key_block[NUM_MIXERS * MD5_LENGTH];
  4644. unsigned char key_block2[MD5_LENGTH];
  4645. PRBool isFIPS;
  4646. HASH_HashType hashType;
  4647. PRBool extractValue = PR_TRUE;
  4648. CHECK_FORK();
  4649. if (!slot) {
  4650. return CKR_SESSION_HANDLE_INVALID;
  4651. }
  4652. /*
  4653. * now lets create an object to hang the attributes off of
  4654. */
  4655. if (phKey) *phKey = CK_INVALID_HANDLE;
  4656. key = sftk_NewObject(slot); /* fill in the handle later */
  4657. if (key == NULL) {
  4658. return CKR_HOST_MEMORY;
  4659. }
  4660. isFIPS = (slot->slotID == FIPS_SLOT_ID);
  4661. /*
  4662. * load the template values into the object
  4663. */
  4664. for (i=0; i < (int) ulAttributeCount; i++) {
  4665. crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
  4666. if (crv != CKR_OK) break;
  4667. if (pTemplate[i].type == CKA_KEY_TYPE) {
  4668. keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue;
  4669. }
  4670. if (pTemplate[i].type == CKA_VALUE_LEN) {
  4671. keySize = *(CK_ULONG *)pTemplate[i].pValue;
  4672. }
  4673. }
  4674. if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
  4675. if (keySize == 0) {
  4676. keySize = sftk_MapKeySize(keyType);
  4677. }
  4678. switch (pMechanism->mechanism) {
  4679. case CKM_NSS_JPAKE_ROUND2_SHA1: /* fall through */
  4680. case CKM_NSS_JPAKE_ROUND2_SHA256: /* fall through */
  4681. case CKM_NSS_JPAKE_ROUND2_SHA384: /* fall through */
  4682. case CKM_NSS_JPAKE_ROUND2_SHA512:
  4683. extractValue = PR_FALSE;
  4684. classType = CKO_PRIVATE_KEY;
  4685. break;
  4686. case CKM_NSS_JPAKE_FINAL_SHA1: /* fall through */
  4687. case CKM_NSS_JPAKE_FINAL_SHA256: /* fall through */
  4688. case CKM_NSS_JPAKE_FINAL_SHA384: /* fall through */
  4689. case CKM_NSS_JPAKE_FINAL_SHA512:
  4690. extractValue = PR_FALSE;
  4691. /* fall through */
  4692. default:
  4693. classType = CKO_SECRET_KEY;
  4694. }
  4695. crv = sftk_forceAttribute (key,CKA_CLASS,&classType,sizeof(classType));
  4696. if (crv != CKR_OK) {
  4697. sftk_FreeObject(key);
  4698. return crv;
  4699. }
  4700. /* look up the base key we're deriving with */
  4701. session = sftk_SessionFromHandle(hSession);
  4702. if (session == NULL) {
  4703. sftk_FreeObject(key);
  4704. return CKR_SESSION_HANDLE_INVALID;
  4705. }
  4706. sourceKey = sftk_ObjectFromHandle(hBaseKey,session);
  4707. sftk_FreeSession(session);
  4708. if (sourceKey == NULL) {
  4709. sftk_FreeObject(key);
  4710. return CKR_KEY_HANDLE_INVALID;
  4711. }
  4712. if (extractValue) {
  4713. /* get the value of the base key */
  4714. att = sftk_FindAttribute(sourceKey,CKA_VALUE);
  4715. if (att == NULL) {
  4716. sftk_FreeObject(key);
  4717. sftk_FreeObject(sourceKey);
  4718. return CKR_KEY_HANDLE_INVALID;
  4719. }
  4720. }
  4721. switch (pMechanism->mechanism) {
  4722. /*
  4723. * generate the master secret
  4724. */
  4725. case CKM_TLS_MASTER_KEY_DERIVE:
  4726. case CKM_TLS_MASTER_KEY_DERIVE_DH:
  4727. isTLS = PR_TRUE;
  4728. /* fall thru */
  4729. case CKM_SSL3_MASTER_KEY_DERIVE:
  4730. case CKM_SSL3_MASTER_KEY_DERIVE_DH:
  4731. {
  4732. CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master;
  4733. SSL3RSAPreMasterSecret * rsa_pms;
  4734. unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
  4735. if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) ||
  4736. (pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH))
  4737. isDH = PR_TRUE;
  4738. /* first do the consistancy checks */
  4739. if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
  4740. crv = CKR_KEY_TYPE_INCONSISTENT;
  4741. break;
  4742. }
  4743. att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE);
  4744. if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
  4745. CKK_GENERIC_SECRET)) {
  4746. if (att2) sftk_FreeAttribute(att2);
  4747. crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
  4748. break;
  4749. }
  4750. sftk_FreeAttribute(att2);
  4751. if (keyType != CKK_GENERIC_SECRET) {
  4752. crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
  4753. break;
  4754. }
  4755. if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
  4756. crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
  4757. break;
  4758. }
  4759. /* finally do the key gen */
  4760. ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
  4761. pMechanism->pParameter;
  4762. PORT_Memcpy(crsrdata,
  4763. ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
  4764. PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
  4765. ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
  4766. if (ssl3_master->pVersion) {
  4767. SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
  4768. rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
  4769. /* don't leak more key material then necessary for SSL to work */
  4770. if ((sessKey == NULL) || sessKey->wasDerived) {
  4771. ssl3_master->pVersion->major = 0xff;
  4772. ssl3_master->pVersion->minor = 0xff;
  4773. } else {
  4774. ssl3_master->pVersion->major = rsa_pms->client_version[0];
  4775. ssl3_master->pVersion->minor = rsa_pms->client_version[1];
  4776. }
  4777. }
  4778. if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH) {
  4779. crv = CKR_MECHANISM_PARAM_INVALID;
  4780. break;
  4781. }
  4782. if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH) {
  4783. crv = CKR_MECHANISM_PARAM_INVALID;
  4784. break;
  4785. }
  4786. if (isTLS) {
  4787. SECStatus status;
  4788. SECItem crsr = { siBuffer, NULL, 0 };
  4789. SECItem master = { siBuffer, NULL, 0 };
  4790. SECItem pms = { siBuffer, NULL, 0 };
  4791. crsr.data = crsrdata;
  4792. crsr.len = sizeof crsrdata;
  4793. master.data = key_block;
  4794. master.len = SSL3_MASTER_SECRET_LENGTH;
  4795. pms.data = (unsigned char*)att->attrib.pValue;
  4796. pms.len = att->attrib.ulValueLen;
  4797. status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
  4798. if (status != SECSuccess) {
  4799. crv = CKR_FUNCTION_FAILED;
  4800. break;
  4801. }
  4802. } else {
  4803. /* now allocate the hash contexts */
  4804. md5 = MD5_NewContext();
  4805. if (md5 == NULL) {
  4806. crv = CKR_HOST_MEMORY;
  4807. break;
  4808. }
  4809. sha = SHA1_NewContext();
  4810. if (sha == NULL) {
  4811. PORT_Free(md5);
  4812. crv = CKR_HOST_MEMORY;
  4813. break;
  4814. }
  4815. for (i = 0; i < 3; i++) {
  4816. SHA1_Begin(sha);
  4817. SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
  4818. SHA1_Update(sha, (const unsigned char*)att->attrib.pValue,
  4819. att->attrib.ulValueLen);
  4820. SHA1_Update(sha, crsrdata, sizeof crsrdata);
  4821. SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
  4822. PORT_Assert(outLen == SHA1_LENGTH);
  4823. MD5_Begin(md5);
  4824. MD5_Update(md5, (const unsigned char*)att->attrib.pValue,
  4825. att->attrib.ulValueLen);
  4826. MD5_Update(md5, sha_out, outLen);
  4827. MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
  4828. PORT_Assert(outLen == MD5_LENGTH);
  4829. }
  4830. PORT_Free(md5);
  4831. PORT_Free(sha);
  4832. }
  4833. /* store the results */
  4834. crv = sftk_forceAttribute
  4835. (key,CKA_VALUE,key_block,SSL3_MASTER_SECRET_LENGTH);
  4836. if (crv != CKR_OK) break;
  4837. keyType = CKK_GENERIC_SECRET;
  4838. crv = sftk_forceAttribute (key,CKA_KEY_TYPE,&keyType,sizeof(keyType));
  4839. if (isTLS) {
  4840. /* TLS's master secret is used to "sign" finished msgs with PRF. */
  4841. /* XXX This seems like a hack. But SFTK_Derive only accepts
  4842. * one "operation" argument. */
  4843. crv = sftk_forceAttribute(key,CKA_SIGN, &cktrue,sizeof(CK_BBOOL));
  4844. if (crv != CKR_OK) break;
  4845. crv = sftk_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
  4846. if (crv != CKR_OK) break;
  4847. /* While we're here, we might as well force this, too. */
  4848. crv = sftk_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
  4849. if (crv != CKR_OK) break;
  4850. }
  4851. break;
  4852. }
  4853. case CKM_TLS_KEY_AND_MAC_DERIVE:
  4854. isTLS = PR_TRUE;
  4855. /* fall thru */
  4856. case CKM_SSL3_KEY_AND_MAC_DERIVE:
  4857. {
  4858. CK_SSL3_KEY_MAT_PARAMS *ssl3_keys;
  4859. CK_SSL3_KEY_MAT_OUT * ssl3_keys_out;
  4860. CK_ULONG effKeySize;
  4861. unsigned int block_needed;
  4862. unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2];
  4863. unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
  4864. crv = sftk_DeriveSensitiveCheck(sourceKey,key);
  4865. if (crv != CKR_OK) break;
  4866. if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH) {
  4867. crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
  4868. break;
  4869. }
  4870. att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE);
  4871. if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
  4872. CKK_GENERIC_SECRET)) {
  4873. if (att2) sftk_FreeAttribute(att2);
  4874. crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
  4875. break;
  4876. }
  4877. sftk_FreeAttribute(att2);
  4878. md5 = MD5_NewContext();
  4879. if (md5 == NULL) {
  4880. crv = CKR_HOST_MEMORY;
  4881. break;
  4882. }
  4883. sha = SHA1_NewContext();
  4884. if (sha == NULL) {
  4885. PORT_Free(md5);
  4886. crv = CKR_HOST_MEMORY;
  4887. break;
  4888. }
  4889. ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter;
  4890. PORT_Memcpy(srcrdata,
  4891. ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
  4892. PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH,
  4893. ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
  4894. PORT_Memcpy(crsrdata,
  4895. ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
  4896. PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
  4897. ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
  4898. /*
  4899. * clear out our returned keys so we can recover on failure
  4900. */
  4901. ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
  4902. ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE;
  4903. ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE;
  4904. ssl3_keys_out->hClientKey = CK_INVALID_HANDLE;
  4905. ssl3_keys_out->hServerKey = CK_INVALID_HANDLE;
  4906. /*
  4907. * How much key material do we need?
  4908. */
  4909. macSize = ssl3_keys->ulMacSizeInBits/8;
  4910. effKeySize = ssl3_keys->ulKeySizeInBits/8;
  4911. IVSize = ssl3_keys->ulIVSizeInBits/8;
  4912. if (keySize == 0) {
  4913. effKeySize = keySize;
  4914. }
  4915. block_needed = 2 * (macSize + effKeySize +
  4916. ((!ssl3_keys->bIsExport) * IVSize));
  4917. PORT_Assert(block_needed <= sizeof key_block);
  4918. if (block_needed > sizeof key_block)
  4919. block_needed = sizeof key_block;
  4920. /*
  4921. * generate the key material: This looks amazingly similar to the
  4922. * PMS code, and is clearly crying out for a function to provide it.
  4923. */
  4924. if (isTLS) {
  4925. SECStatus status;
  4926. SECItem srcr = { siBuffer, NULL, 0 };
  4927. SECItem keyblk = { siBuffer, NULL, 0 };
  4928. SECItem master = { siBuffer, NULL, 0 };
  4929. srcr.data = srcrdata;
  4930. srcr.len = sizeof srcrdata;
  4931. keyblk.data = key_block;
  4932. keyblk.len = block_needed;
  4933. master.data = (unsigned char*)att->attrib.pValue;
  4934. master.len = att->attrib.ulValueLen;
  4935. status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
  4936. isFIPS);
  4937. if (status != SECSuccess) {
  4938. goto key_and_mac_derive_fail;
  4939. }
  4940. } else {
  4941. unsigned int block_bytes = 0;
  4942. /* key_block =
  4943. * MD5(master_secret + SHA('A' + master_secret +
  4944. * ServerHello.random + ClientHello.random)) +
  4945. * MD5(master_secret + SHA('BB' + master_secret +
  4946. * ServerHello.random + ClientHello.random)) +
  4947. * MD5(master_secret + SHA('CCC' + master_secret +
  4948. * ServerHello.random + ClientHello.random)) +
  4949. * [...];
  4950. */
  4951. for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) {
  4952. SHA1_Begin(sha);
  4953. SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
  4954. SHA1_Update(sha, (const unsigned char*)att->attrib.pValue,
  4955. att->attrib.ulValueLen);
  4956. SHA1_Update(sha, srcrdata, sizeof srcrdata);
  4957. SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
  4958. PORT_Assert(outLen == SHA1_LENGTH);
  4959. MD5_Begin(md5);
  4960. MD5_Update(md5, (const unsigned char*)att->attrib.pValue,
  4961. att->attrib.ulValueLen);
  4962. MD5_Update(md5, sha_out, outLen);
  4963. MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
  4964. PORT_Assert(outLen == MD5_LENGTH);
  4965. block_bytes += outLen;
  4966. }
  4967. }
  4968. /*
  4969. * Put the key material where it goes.
  4970. */
  4971. i = 0; /* now shows how much consumed */
  4972. /*
  4973. * The key_block is partitioned as follows:
  4974. * client_write_MAC_secret[CipherSpec.hash_size]
  4975. */
  4976. crv = sftk_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize,
  4977. &ssl3_keys_out->hClientMacSecret);
  4978. if (crv != CKR_OK)
  4979. goto key_and_mac_derive_fail;
  4980. i += macSize;
  4981. /*
  4982. * server_write_MAC_secret[CipherSpec.hash_size]
  4983. */
  4984. crv = sftk_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize,
  4985. &ssl3_keys_out->hServerMacSecret);
  4986. if (crv != CKR_OK) {
  4987. goto key_and_mac_derive_fail;
  4988. }
  4989. i += macSize;
  4990. if (keySize) {
  4991. if (!ssl3_keys->bIsExport) {
  4992. /*
  4993. ** Generate Domestic write keys and IVs.
  4994. ** client_write_key[CipherSpec.key_material]
  4995. */
  4996. crv = sftk_buildSSLKey(hSession,key,PR_FALSE,&key_block[i],
  4997. keySize, &ssl3_keys_out->hClientKey);
  4998. if (crv != CKR_OK) {
  4999. goto key_and_mac_derive_fail;
  5000. }
  5001. i += keySize;
  5002. /*
  5003. ** server_write_key[CipherSpec.key_material]
  5004. */
  5005. crv = sftk_buildSSLKey(hSession,key,PR_FALSE,&key_block[i],
  5006. keySize, &ssl3_keys_out->hServerKey);
  5007. if (crv != CKR_OK) {
  5008. goto key_and_mac_derive_fail;
  5009. }
  5010. i += keySize;
  5011. /*
  5012. ** client_write_IV[CipherSpec.IV_size]
  5013. */
  5014. if (IVSize > 0) {
  5015. PORT_Memcpy(ssl3_keys_out->pIVClient,
  5016. &key_block[i], IVSize);
  5017. i += IVSize;
  5018. }
  5019. /*
  5020. ** server_write_IV[CipherSpec.IV_size]
  5021. */
  5022. if (IVSize > 0) {
  5023. PORT_Memcpy(ssl3_keys_out->pIVServer,
  5024. &key_block[i], IVSize);
  5025. i += IVSize;
  5026. }
  5027. PORT_Assert(i <= sizeof key_block);
  5028. } else if (!isTLS) {
  5029. /*
  5030. ** Generate SSL3 Export write keys and IVs.
  5031. ** client_write_key[CipherSpec.key_material]
  5032. ** final_client_write_key = MD5(client_write_key +
  5033. ** ClientHello.random + ServerHello.random);
  5034. */
  5035. MD5_Begin(md5);
  5036. MD5_Update(md5, &key_block[i], effKeySize);
  5037. MD5_Update(md5, crsrdata, sizeof crsrdata);
  5038. MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
  5039. i += effKeySize;
  5040. crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2,
  5041. keySize,&ssl3_keys_out->hClientKey);
  5042. if (crv != CKR_OK) {
  5043. goto key_and_mac_derive_fail;
  5044. }
  5045. /*
  5046. ** server_write_key[CipherSpec.key_material]
  5047. ** final_server_write_key = MD5(server_write_key +
  5048. ** ServerHello.random + ClientHello.random);
  5049. */
  5050. MD5_Begin(md5);
  5051. MD5_Update(md5, &key_block[i], effKeySize);
  5052. MD5_Update(md5, srcrdata, sizeof srcrdata);
  5053. MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
  5054. i += effKeySize;
  5055. crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2,
  5056. keySize,&ssl3_keys_out->hServerKey);
  5057. if (crv != CKR_OK) {
  5058. goto key_and_mac_derive_fail;
  5059. }
  5060. /*
  5061. ** client_write_IV =
  5062. ** MD5(ClientHello.random + ServerHello.random);
  5063. */
  5064. MD5_Begin(md5);
  5065. MD5_Update(md5, crsrdata, sizeof crsrdata);
  5066. MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
  5067. PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize);
  5068. /*
  5069. ** server_write_IV =
  5070. ** MD5(ServerHello.random + ClientHello.random);
  5071. */
  5072. MD5_Begin(md5);
  5073. MD5_Update(md5, srcrdata, sizeof srcrdata);
  5074. MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
  5075. PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize);
  5076. } else {
  5077. /*
  5078. ** Generate TLS Export write keys and IVs.
  5079. */
  5080. SECStatus status;
  5081. SECItem secret = { siBuffer, NULL, 0 };
  5082. SECItem crsr = { siBuffer, NULL, 0 };
  5083. SECItem keyblk = { siBuffer, NULL, 0 };
  5084. /*
  5085. ** client_write_key[CipherSpec.key_material]
  5086. ** final_client_write_key = PRF(client_write_key,
  5087. ** "client write key",
  5088. ** client_random + server_random);
  5089. */
  5090. secret.data = &key_block[i];
  5091. secret.len = effKeySize;
  5092. i += effKeySize;
  5093. crsr.data = crsrdata;
  5094. crsr.len = sizeof crsrdata;
  5095. keyblk.data = key_block2;
  5096. keyblk.len = sizeof key_block2;
  5097. status = TLS_PRF(&secret, "client write key", &crsr, &keyblk,
  5098. isFIPS);
  5099. if (status != SECSuccess) {
  5100. goto key_and_mac_derive_fail;
  5101. }
  5102. crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2,
  5103. keySize, &ssl3_keys_out->hClientKey);
  5104. if (crv != CKR_OK) {
  5105. goto key_and_mac_derive_fail;
  5106. }
  5107. /*
  5108. ** server_write_key[CipherSpec.key_material]
  5109. ** final_server_write_key = PRF(server_write_key,
  5110. ** "server write key",
  5111. ** client_random + server_random);
  5112. */
  5113. secret.data = &key_block[i];
  5114. secret.len = effKeySize;
  5115. i += effKeySize;
  5116. keyblk.data = key_block2;
  5117. keyblk.len = sizeof key_block2;
  5118. status = TLS_PRF(&secret, "server write key", &crsr, &keyblk,
  5119. isFIPS);
  5120. if (status != SECSuccess) {
  5121. goto key_and_mac_derive_fail;
  5122. }
  5123. crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2,
  5124. keySize, &ssl3_keys_out->hServerKey);
  5125. if (crv != CKR_OK) {
  5126. goto key_and_mac_derive_fail;
  5127. }
  5128. /*
  5129. ** iv_block = PRF("", "IV block",
  5130. ** client_random + server_random);
  5131. ** client_write_IV[SecurityParameters.IV_size]
  5132. ** server_write_IV[SecurityParameters.IV_size]
  5133. */
  5134. if (IVSize) {
  5135. secret.data = NULL;
  5136. secret.len = 0;
  5137. keyblk.data = &key_block[i];
  5138. keyblk.len = 2 * IVSize;
  5139. status = TLS_PRF(&secret, "IV block", &crsr, &keyblk,
  5140. isFIPS);
  5141. if (status != SECSuccess) {
  5142. goto key_and_mac_derive_fail;
  5143. }
  5144. PORT_Memcpy(ssl3_keys_out->pIVClient, keyblk.data, IVSize);
  5145. PORT_Memcpy(ssl3_keys_out->pIVServer, keyblk.data + IVSize,
  5146. IVSize);
  5147. }
  5148. }
  5149. }
  5150. crv = CKR_OK;
  5151. if (0) {
  5152. key_and_mac_derive_fail:
  5153. if (crv == CKR_OK)
  5154. crv = CKR_FUNCTION_FAILED;
  5155. sftk_freeSSLKeys(hSession, ssl3_keys_out);
  5156. }
  5157. MD5_DestroyContext(md5, PR_TRUE);
  5158. SHA1_DestroyContext(sha, PR_TRUE);
  5159. sftk_FreeObject(key);
  5160. key = NULL;
  5161. break;
  5162. }
  5163. case CKM_CONCATENATE_BASE_AND_KEY:
  5164. {
  5165. SFTKObject *newKey;
  5166. crv = sftk_DeriveSensitiveCheck(sourceKey,key);
  5167. if (crv != CKR_OK) break;
  5168. session = sftk_SessionFromHandle(hSession);
  5169. if (session == NULL) {
  5170. crv = CKR_SESSION_HANDLE_INVALID;
  5171. break;
  5172. }
  5173. newKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *)
  5174. pMechanism->pParameter,session);
  5175. sftk_FreeSession(session);
  5176. if ( newKey == NULL) {
  5177. crv = CKR_KEY_HANDLE_INVALID;
  5178. break;
  5179. }
  5180. if (sftk_isTrue(newKey,CKA_SENSITIVE)) {
  5181. crv = sftk_forceAttribute(newKey,CKA_SENSITIVE,&cktrue,
  5182. sizeof(CK_BBOOL));
  5183. if (crv != CKR_OK) {
  5184. sftk_FreeObject(newKey);
  5185. break;
  5186. }
  5187. }
  5188. att2 = sftk_FindAttribute(newKey,CKA_VALUE);
  5189. if (att2 == NULL) {
  5190. sftk_FreeObject(newKey);
  5191. crv = CKR_KEY_HANDLE_INVALID;
  5192. break;
  5193. }
  5194. tmpKeySize = att->attrib.ulValueLen+att2->attrib.ulValueLen;
  5195. if (keySize == 0) keySize = tmpKeySize;
  5196. if (keySize > tmpKeySize) {
  5197. sftk_FreeObject(newKey);
  5198. sftk_FreeAttribute(att2);
  5199. crv = CKR_TEMPLATE_INCONSISTENT;
  5200. break;
  5201. }
  5202. buf = (unsigned char*)PORT_Alloc(tmpKeySize);
  5203. if (buf == NULL) {
  5204. sftk_FreeAttribute(att2);
  5205. sftk_FreeObject(newKey);
  5206. crv = CKR_HOST_MEMORY;
  5207. break;
  5208. }
  5209. PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen);
  5210. PORT_Memcpy(buf+att->attrib.ulValueLen,
  5211. att2->attrib.pValue,att2->attrib.ulValueLen);
  5212. crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
  5213. PORT_ZFree(buf,tmpKeySize);
  5214. sftk_FreeAttribute(att2);
  5215. sftk_FreeObject(newKey);
  5216. break;
  5217. }
  5218. case CKM_CONCATENATE_BASE_AND_DATA:
  5219. crv = sftk_DeriveSensitiveCheck(sourceKey,key);
  5220. if (crv != CKR_OK) break;
  5221. stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter;
  5222. tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
  5223. if (keySize == 0) keySize = tmpKeySize;
  5224. if (keySize > tmpKeySize) {
  5225. crv = CKR_TEMPLATE_INCONSISTENT;
  5226. break;
  5227. }
  5228. buf = (unsigned char*)PORT_Alloc(tmpKeySize);
  5229. if (buf == NULL) {
  5230. crv = CKR_HOST_MEMORY;
  5231. break;
  5232. }
  5233. PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen);
  5234. PORT_Memcpy(buf+att->attrib.ulValueLen,stringPtr->pData,
  5235. stringPtr->ulLen);
  5236. crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
  5237. PORT_ZFree(buf,tmpKeySize);
  5238. break;
  5239. case CKM_CONCATENATE_DATA_AND_BASE:
  5240. crv = sftk_DeriveSensitiveCheck(sourceKey,key);
  5241. if (crv != CKR_OK) break;
  5242. stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
  5243. tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
  5244. if (keySize == 0) keySize = tmpKeySize;
  5245. if (keySize > tmpKeySize) {
  5246. crv = CKR_TEMPLATE_INCONSISTENT;
  5247. break;
  5248. }
  5249. buf = (unsigned char*)PORT_Alloc(tmpKeySize);
  5250. if (buf == NULL) {
  5251. crv = CKR_HOST_MEMORY;
  5252. break;
  5253. }
  5254. PORT_Memcpy(buf,stringPtr->pData,stringPtr->ulLen);
  5255. PORT_Memcpy(buf+stringPtr->ulLen,att->attrib.pValue,
  5256. att->attrib.ulValueLen);
  5257. crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
  5258. PORT_ZFree(buf,tmpKeySize);
  5259. break;
  5260. case CKM_XOR_BASE_AND_DATA:
  5261. crv = sftk_DeriveSensitiveCheck(sourceKey,key);
  5262. if (crv != CKR_OK) break;
  5263. stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
  5264. tmpKeySize = PR_MIN(att->attrib.ulValueLen,stringPtr->ulLen);
  5265. if (keySize == 0) keySize = tmpKeySize;
  5266. if (keySize > tmpKeySize) {
  5267. crv = CKR_TEMPLATE_INCONSISTENT;
  5268. break;
  5269. }
  5270. buf = (unsigned char*)PORT_Alloc(keySize);
  5271. if (buf == NULL) {
  5272. crv = CKR_HOST_MEMORY;
  5273. break;
  5274. }
  5275. PORT_Memcpy(buf,att->attrib.pValue,keySize);
  5276. for (i=0; i < (int)keySize; i++) {
  5277. buf[i] ^= stringPtr->pData[i];
  5278. }
  5279. crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
  5280. PORT_ZFree(buf,keySize);
  5281. break;
  5282. case CKM_EXTRACT_KEY_FROM_KEY:
  5283. {
  5284. /* the following assumes 8 bits per byte */
  5285. CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter;
  5286. CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */
  5287. CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */
  5288. crv = sftk_DeriveSensitiveCheck(sourceKey,key);
  5289. if (crv != CKR_OK) break;
  5290. if (keySize == 0) {
  5291. crv = CKR_TEMPLATE_INCOMPLETE;
  5292. break;
  5293. }
  5294. /* make sure we have enough bits in the original key */
  5295. if (att->attrib.ulValueLen <
  5296. (offset + keySize + ((shift != 0)? 1 :0)) ) {
  5297. crv = CKR_MECHANISM_PARAM_INVALID;
  5298. break;
  5299. }
  5300. buf = (unsigned char*)PORT_Alloc(keySize);
  5301. if (buf == NULL) {
  5302. crv = CKR_HOST_MEMORY;
  5303. break;
  5304. }
  5305. /* copy the bits we need into the new key */
  5306. for (i=0; i < (int)keySize; i++) {
  5307. unsigned char *value =
  5308. ((unsigned char *)att->attrib.pValue)+offset+i;
  5309. if (shift) {
  5310. buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift));
  5311. } else {
  5312. buf[i] = value[0];
  5313. }
  5314. }
  5315. crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
  5316. PORT_ZFree(buf,keySize);
  5317. break;
  5318. }
  5319. case CKM_MD2_KEY_DERIVATION:
  5320. if (keySize == 0) keySize = MD2_LENGTH;
  5321. if (keySize > MD2_LENGTH) {
  5322. crv = CKR_TEMPLATE_INCONSISTENT;
  5323. break;
  5324. }
  5325. /* now allocate the hash contexts */
  5326. md2 = MD2_NewContext();
  5327. if (md2 == NULL) {
  5328. crv = CKR_HOST_MEMORY;
  5329. break;
  5330. }
  5331. MD2_Begin(md2);
  5332. MD2_Update(md2,(const unsigned char*)att->attrib.pValue,
  5333. att->attrib.ulValueLen);
  5334. MD2_End(md2,key_block,&outLen,MD2_LENGTH);
  5335. MD2_DestroyContext(md2, PR_TRUE);
  5336. crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize);
  5337. break;
  5338. case CKM_MD5_KEY_DERIVATION:
  5339. if (keySize == 0) keySize = MD5_LENGTH;
  5340. if (keySize > MD5_LENGTH) {
  5341. crv = CKR_TEMPLATE_INCONSISTENT;
  5342. break;
  5343. }
  5344. /* now allocate the hash contexts */
  5345. md5 = MD5_NewContext();
  5346. if (md5 == NULL) {
  5347. crv = CKR_HOST_MEMORY;
  5348. break;
  5349. }
  5350. MD5_Begin(md5);
  5351. MD5_Update(md5,(const unsigned char*)att->attrib.pValue,
  5352. att->attrib.ulValueLen);
  5353. MD5_End(md5,key_block,&outLen,MD5_LENGTH);
  5354. MD5_DestroyContext(md5, PR_TRUE);
  5355. crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize);
  5356. break;
  5357. case CKM_SHA1_KEY_DERIVATION:
  5358. if (keySize == 0) keySize = SHA1_LENGTH;
  5359. if (keySize > SHA1_LENGTH) {
  5360. crv = CKR_TEMPLATE_INCONSISTENT;
  5361. break;
  5362. }
  5363. /* now allocate the hash contexts */
  5364. sha = SHA1_NewContext();
  5365. if (sha == NULL) {
  5366. crv = CKR_HOST_MEMORY;
  5367. break;
  5368. }
  5369. SHA1_Begin(sha);
  5370. SHA1_Update(sha,(const unsigned char*)att->attrib.pValue,
  5371. att->attrib.ulValueLen);
  5372. SHA1_End(sha,key_block,&outLen,SHA1_LENGTH);
  5373. SHA1_DestroyContext(sha, PR_TRUE);
  5374. crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize);
  5375. break;
  5376. case CKM_DH_PKCS_DERIVE:
  5377. {
  5378. SECItem derived, dhPublic;
  5379. SECItem dhPrime, dhValue;
  5380. /* sourceKey - values for the local existing low key */
  5381. /* get prime and value attributes */
  5382. crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME);
  5383. if (crv != SECSuccess) break;
  5384. crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE);
  5385. if (crv != SECSuccess) {
  5386. PORT_Free(dhPrime.data);
  5387. break;
  5388. }
  5389. dhPublic.data = pMechanism->pParameter;
  5390. dhPublic.len = pMechanism->ulParameterLen;
  5391. /* calculate private value - oct */
  5392. rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
  5393. PORT_Free(dhPrime.data);
  5394. PORT_Free(dhValue.data);
  5395. if (rv == SECSuccess) {
  5396. sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
  5397. PORT_ZFree(derived.data, derived.len);
  5398. } else
  5399. crv = CKR_HOST_MEMORY;
  5400. break;
  5401. }
  5402. #ifdef NSS_ENABLE_ECC
  5403. case CKM_ECDH1_DERIVE:
  5404. case CKM_ECDH1_COFACTOR_DERIVE:
  5405. {
  5406. SECItem ecScalar, ecPoint;
  5407. SECItem tmp;
  5408. PRBool withCofactor = PR_FALSE;
  5409. unsigned char secret_hash[20];
  5410. unsigned char *secret;
  5411. unsigned char *keyData = NULL;
  5412. int secretlen, curveLen, pubKeyLen;
  5413. CK_ECDH1_DERIVE_PARAMS *mechParams;
  5414. NSSLOWKEYPrivateKey *privKey;
  5415. PLArenaPool *arena = NULL;
  5416. /* Check mechanism parameters */
  5417. mechParams = (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter;
  5418. if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) ||
  5419. ((mechParams->kdf == CKD_NULL) &&
  5420. ((mechParams->ulSharedDataLen != 0) ||
  5421. (mechParams->pSharedData != NULL)))) {
  5422. crv = CKR_MECHANISM_PARAM_INVALID;
  5423. break;
  5424. }
  5425. privKey = sftk_GetPrivKey(sourceKey, CKK_EC, &crv);
  5426. if (privKey == NULL) {
  5427. break;
  5428. }
  5429. /* Now we are working with a non-NULL private key */
  5430. SECITEM_CopyItem(NULL, &ecScalar, &privKey->u.ec.privateValue);
  5431. ecPoint.data = mechParams->pPublicData;
  5432. ecPoint.len = mechParams->ulPublicDataLen;
  5433. curveLen = (privKey->u.ec.ecParams.fieldID.size +7)/8;
  5434. pubKeyLen = (2*curveLen) + 1;
  5435. /* if the len is too small, can't be a valid point */
  5436. if (ecPoint.len < pubKeyLen) {
  5437. goto ec_loser;
  5438. }
  5439. /* if the len is too large, must be an encoded point (length is
  5440. * equal case just falls through */
  5441. if (ecPoint.len > pubKeyLen) {
  5442. SECItem newPoint;
  5443. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  5444. if (arena == NULL) {
  5445. goto ec_loser;
  5446. }
  5447. rv = SEC_QuickDERDecodeItem(arena, &newPoint,
  5448. SEC_ASN1_GET(SEC_OctetStringTemplate),
  5449. &ecPoint);
  5450. if (rv != SECSuccess) {
  5451. goto ec_loser;
  5452. }
  5453. ecPoint = newPoint;
  5454. }
  5455. if (pMechanism->mechanism == CKM_ECDH1_COFACTOR_DERIVE) {
  5456. withCofactor = PR_TRUE;
  5457. } else {
  5458. /* When not using cofactor derivation, one should
  5459. * validate the public key to avoid small subgroup
  5460. * attacks.
  5461. */
  5462. if (EC_ValidatePublicKey(&privKey->u.ec.ecParams, &ecPoint)
  5463. != SECSuccess) {
  5464. goto ec_loser;
  5465. }
  5466. }
  5467. rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar,
  5468. withCofactor, &tmp);
  5469. PORT_Free(ecScalar.data);
  5470. ecScalar.data = NULL;
  5471. if (privKey != sourceKey->objectInfo) {
  5472. nsslowkey_DestroyPrivateKey(privKey);
  5473. privKey=NULL;
  5474. }
  5475. if (arena) {
  5476. PORT_FreeArena(arena,PR_FALSE);
  5477. arena=NULL;
  5478. }
  5479. if (rv != SECSuccess) {
  5480. crv = sftk_MapCryptError(PORT_GetError());
  5481. break;
  5482. }
  5483. /*
  5484. * tmp is the raw data created by ECDH_Derive,
  5485. * secret and secretlen are the values we will eventually pass as our
  5486. * generated key.
  5487. */
  5488. secret = tmp.data;
  5489. secretlen = tmp.len;
  5490. /*
  5491. * apply the kdf function.
  5492. */
  5493. if (mechParams->kdf == CKD_SHA1_KDF) {
  5494. /* Compute SHA1 hash */
  5495. PORT_Memset(secret_hash, 0, 20);
  5496. rv = SHA1_HashBuf(secret_hash, tmp.data, tmp.len);
  5497. if (rv != SECSuccess) {
  5498. PORT_ZFree(tmp.data, tmp.len);
  5499. crv = CKR_HOST_MEMORY;
  5500. break;
  5501. }
  5502. secret = secret_hash;
  5503. secretlen = 20;
  5504. }
  5505. /*
  5506. * if keySize is supplied, then we are generating a key of a specific
  5507. * length. This is done by taking the least significant 'keySize'
  5508. * bytes from the unsigned value calculated by ECDH. Note: this may
  5509. * mean padding temp with extra leading zeros from what ECDH_Derive
  5510. * already returned (which itself may contain leading zeros).
  5511. */
  5512. if (keySize) {
  5513. if (secretlen < keySize) {
  5514. keyData = PORT_ZAlloc(keySize);
  5515. if (!keyData) {
  5516. PORT_ZFree(tmp.data, tmp.len);
  5517. crv = CKR_HOST_MEMORY;
  5518. break;
  5519. }
  5520. PORT_Memcpy(&keyData[keySize-secretlen],secret,secretlen);
  5521. secret = keyData;
  5522. } else {
  5523. secret += (secretlen - keySize);
  5524. }
  5525. secretlen = keySize;
  5526. }
  5527. sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
  5528. PORT_ZFree(tmp.data, tmp.len);
  5529. if (keyData) {
  5530. PORT_ZFree(keyData, keySize);
  5531. }
  5532. PORT_Memset(secret_hash, 0, 20);
  5533. break;
  5534. ec_loser:
  5535. crv = CKR_ARGUMENTS_BAD;
  5536. PORT_Free(ecScalar.data);
  5537. if (privKey != sourceKey->objectInfo)
  5538. nsslowkey_DestroyPrivateKey(privKey);
  5539. if (arena) {
  5540. PORT_FreeArena(arena, PR_FALSE);
  5541. }
  5542. break;
  5543. }
  5544. #endif /* NSS_ENABLE_ECC */
  5545. /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */
  5546. case CKM_NSS_HKDF_SHA1: hashType = HASH_AlgSHA1; goto hkdf;
  5547. case CKM_NSS_HKDF_SHA256: hashType = HASH_AlgSHA256; goto hkdf;
  5548. case CKM_NSS_HKDF_SHA384: hashType = HASH_AlgSHA384; goto hkdf;
  5549. case CKM_NSS_HKDF_SHA512: hashType = HASH_AlgSHA512; goto hkdf;
  5550. hkdf: {
  5551. const CK_NSS_HKDFParams * params =
  5552. (const CK_NSS_HKDFParams *) pMechanism->pParameter;
  5553. const SECHashObject * rawHash;
  5554. unsigned hashLen;
  5555. CK_BYTE buf[HASH_LENGTH_MAX];
  5556. /* const */ CK_BYTE * prk; /* psuedo-random key */
  5557. CK_ULONG prkLen;
  5558. const CK_BYTE * okm; /* output keying material */
  5559. rawHash = HASH_GetRawHashObject(hashType);
  5560. if (rawHash == NULL || rawHash->length > sizeof buf) {
  5561. crv = CKR_FUNCTION_FAILED;
  5562. break;
  5563. }
  5564. hashLen = rawHash->length;
  5565. if (pMechanism->ulParameterLen != sizeof(CK_NSS_HKDFParams) ||
  5566. !params || (!params->bExpand && !params->bExtract) ||
  5567. (params->bExtract && params->ulSaltLen > 0 && !params->pSalt) ||
  5568. (params->bExpand && params->ulInfoLen > 0 && !params->pInfo)) {
  5569. crv = CKR_MECHANISM_PARAM_INVALID;
  5570. break;
  5571. }
  5572. if (keySize == 0 || keySize > sizeof key_block ||
  5573. (!params->bExpand && keySize > hashLen) ||
  5574. (params->bExpand && keySize > 255 * hashLen)) {
  5575. crv = CKR_TEMPLATE_INCONSISTENT;
  5576. break;
  5577. }
  5578. crv = sftk_DeriveSensitiveCheck(sourceKey, key);
  5579. if (crv != CKR_OK)
  5580. break;
  5581. /* HKDF-Extract(salt, base key value) */
  5582. if (params->bExtract) {
  5583. CK_BYTE * salt;
  5584. CK_ULONG saltLen;
  5585. HMACContext * hmac;
  5586. unsigned int bufLen;
  5587. salt = params->pSalt;
  5588. saltLen = params->ulSaltLen;
  5589. if (salt == NULL) {
  5590. saltLen = hashLen;
  5591. salt = buf;
  5592. memset(salt, 0, saltLen);
  5593. }
  5594. hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
  5595. if (!hmac) {
  5596. crv = CKR_HOST_MEMORY;
  5597. break;
  5598. }
  5599. HMAC_Begin(hmac);
  5600. HMAC_Update(hmac, (const unsigned char*) att->attrib.pValue,
  5601. att->attrib.ulValueLen);
  5602. HMAC_Finish(hmac, buf, &bufLen, sizeof(buf));
  5603. HMAC_Destroy(hmac, PR_TRUE);
  5604. PORT_Assert(bufLen == rawHash->length);
  5605. prk = buf;
  5606. prkLen = bufLen;
  5607. } else {
  5608. /* PRK = base key value */
  5609. prk = (CK_BYTE*) att->attrib.pValue;
  5610. prkLen = att->attrib.ulValueLen;
  5611. }
  5612. /* HKDF-Expand */
  5613. if (!params->bExpand) {
  5614. okm = prk;
  5615. } else {
  5616. /* T(1) = HMAC-Hash(prk, "" | info | 0x01)
  5617. * T(n) = HMAC-Hash(prk, T(n-1) | info | n
  5618. * key material = T(1) | ... | T(n)
  5619. */
  5620. HMACContext * hmac;
  5621. CK_BYTE i;
  5622. unsigned iterations = PR_ROUNDUP(keySize, hashLen) / hashLen;
  5623. hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
  5624. if (hmac == NULL) {
  5625. crv = CKR_HOST_MEMORY;
  5626. break;
  5627. }
  5628. for (i = 1; i <= iterations; ++i) {
  5629. unsigned len;
  5630. HMAC_Begin(hmac);
  5631. if (i > 1) {
  5632. HMAC_Update(hmac, key_block + ((i-2) * hashLen), hashLen);
  5633. }
  5634. if (params->ulInfoLen != 0) {
  5635. HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
  5636. }
  5637. HMAC_Update(hmac, &i, 1);
  5638. HMAC_Finish(hmac, key_block + ((i-1) * hashLen), &len,
  5639. hashLen);
  5640. PORT_Assert(len == hashLen);
  5641. }
  5642. HMAC_Destroy(hmac, PR_TRUE);
  5643. okm = key_block;
  5644. }
  5645. /* key material = prk */
  5646. crv = sftk_forceAttribute(key, CKA_VALUE, okm, keySize);
  5647. break;
  5648. } /* end of CKM_NSS_HKDF_* */
  5649. case CKM_NSS_JPAKE_ROUND2_SHA1: hashType = HASH_AlgSHA1; goto jpake2;
  5650. case CKM_NSS_JPAKE_ROUND2_SHA256: hashType = HASH_AlgSHA256; goto jpake2;
  5651. case CKM_NSS_JPAKE_ROUND2_SHA384: hashType = HASH_AlgSHA384; goto jpake2;
  5652. case CKM_NSS_JPAKE_ROUND2_SHA512: hashType = HASH_AlgSHA512; goto jpake2;
  5653. jpake2:
  5654. if (pMechanism->pParameter == NULL ||
  5655. pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound2Params))
  5656. crv = CKR_MECHANISM_PARAM_INVALID;
  5657. if (crv == CKR_OK && sftk_isTrue(key, CKA_TOKEN))
  5658. crv = CKR_TEMPLATE_INCONSISTENT;
  5659. if (crv == CKR_OK)
  5660. crv = sftk_DeriveSensitiveCheck(sourceKey, key);
  5661. if (crv == CKR_OK)
  5662. crv = jpake_Round2(hashType,
  5663. (CK_NSS_JPAKERound2Params *) pMechanism->pParameter,
  5664. sourceKey, key);
  5665. break;
  5666. case CKM_NSS_JPAKE_FINAL_SHA1: hashType = HASH_AlgSHA1; goto jpakeFinal;
  5667. case CKM_NSS_JPAKE_FINAL_SHA256: hashType = HASH_AlgSHA256; goto jpakeFinal;
  5668. case CKM_NSS_JPAKE_FINAL_SHA384: hashType = HASH_AlgSHA384; goto jpakeFinal;
  5669. case CKM_NSS_JPAKE_FINAL_SHA512: hashType = HASH_AlgSHA512; goto jpakeFinal;
  5670. jpakeFinal:
  5671. if (pMechanism->pParameter == NULL ||
  5672. pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKEFinalParams))
  5673. crv = CKR_MECHANISM_PARAM_INVALID;
  5674. /* We purposely do not do the derive sensitivity check; we want to be
  5675. able to derive non-sensitive keys while allowing the ROUND1 and
  5676. ROUND2 keys to be sensitive (which they always are, since they are
  5677. in the CKO_PRIVATE_KEY class). The caller must include CKA_SENSITIVE
  5678. in the template in order for the resultant keyblock key to be
  5679. sensitive.
  5680. */
  5681. if (crv == CKR_OK)
  5682. crv = jpake_Final(hashType,
  5683. (CK_NSS_JPAKEFinalParams *) pMechanism->pParameter,
  5684. sourceKey, key);
  5685. break;
  5686. default:
  5687. crv = CKR_MECHANISM_INVALID;
  5688. }
  5689. if (att) {
  5690. sftk_FreeAttribute(att);
  5691. }
  5692. sftk_FreeObject(sourceKey);
  5693. if (crv != CKR_OK) {
  5694. if (key) sftk_FreeObject(key);
  5695. return crv;
  5696. }
  5697. /* link the key object into the list */
  5698. if (key) {
  5699. SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
  5700. PORT_Assert(sessKey);
  5701. /* get the session */
  5702. sessKey->wasDerived = PR_TRUE;
  5703. session = sftk_SessionFromHandle(hSession);
  5704. if (session == NULL) {
  5705. sftk_FreeObject(key);
  5706. return CKR_HOST_MEMORY;
  5707. }
  5708. crv = sftk_handleObject(key,session);
  5709. sftk_FreeSession(session);
  5710. *phKey = key->handle;
  5711. sftk_FreeObject(key);
  5712. }
  5713. return crv;
  5714. }
  5715. /* NSC_GetFunctionStatus obtains an updated status of a function running
  5716. * in parallel with an application. */
  5717. CK_RV NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
  5718. {
  5719. CHECK_FORK();
  5720. return CKR_FUNCTION_NOT_PARALLEL;
  5721. }
  5722. /* NSC_CancelFunction cancels a function running in parallel */
  5723. CK_RV NSC_CancelFunction(CK_SESSION_HANDLE hSession)
  5724. {
  5725. CHECK_FORK();
  5726. return CKR_FUNCTION_NOT_PARALLEL;
  5727. }
  5728. /* NSC_GetOperationState saves the state of the cryptographic
  5729. *operation in a session.
  5730. * NOTE: This code only works for digest functions for now. eventually need
  5731. * to add full flatten/resurect to our state stuff so that all types of state
  5732. * can be saved */
  5733. CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession,
  5734. CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
  5735. {
  5736. SFTKSessionContext *context;
  5737. SFTKSession *session;
  5738. CK_RV crv;
  5739. CK_ULONG pOSLen = *pulOperationStateLen;
  5740. CHECK_FORK();
  5741. /* make sure we're legal */
  5742. crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
  5743. if (crv != CKR_OK) return crv;
  5744. *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE)
  5745. + sizeof(SFTKContextType);
  5746. if (pOperationState == NULL) {
  5747. sftk_FreeSession(session);
  5748. return CKR_OK;
  5749. } else {
  5750. if (pOSLen < *pulOperationStateLen) {
  5751. return CKR_BUFFER_TOO_SMALL;
  5752. }
  5753. }
  5754. PORT_Memcpy(pOperationState,&context->type,sizeof(SFTKContextType));
  5755. pOperationState += sizeof(SFTKContextType);
  5756. PORT_Memcpy(pOperationState,&context->currentMech,
  5757. sizeof(CK_MECHANISM_TYPE));
  5758. pOperationState += sizeof(CK_MECHANISM_TYPE);
  5759. PORT_Memcpy(pOperationState,context->cipherInfo,context->cipherInfoLen);
  5760. sftk_FreeSession(session);
  5761. return CKR_OK;
  5762. }
  5763. #define sftk_Decrement(stateSize,len) \
  5764. stateSize = ((stateSize) > (CK_ULONG)(len)) ? \
  5765. ((stateSize) - (CK_ULONG)(len)) : 0;
  5766. /* NSC_SetOperationState restores the state of the cryptographic
  5767. * operation in a session. This is coded like it can restore lots of
  5768. * states, but it only works for truly flat cipher structures. */
  5769. CK_RV NSC_SetOperationState(CK_SESSION_HANDLE hSession,
  5770. CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
  5771. CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
  5772. {
  5773. SFTKSessionContext *context;
  5774. SFTKSession *session;
  5775. SFTKContextType type;
  5776. CK_MECHANISM mech;
  5777. CK_RV crv = CKR_OK;
  5778. CHECK_FORK();
  5779. while (ulOperationStateLen != 0) {
  5780. /* get what type of state we're dealing with... */
  5781. PORT_Memcpy(&type,pOperationState, sizeof(SFTKContextType));
  5782. /* fix up session contexts based on type */
  5783. session = sftk_SessionFromHandle(hSession);
  5784. if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
  5785. context = sftk_ReturnContextByType(session, type);
  5786. sftk_SetContextByType(session, type, NULL);
  5787. if (context) {
  5788. sftk_FreeContext(context);
  5789. }
  5790. pOperationState += sizeof(SFTKContextType);
  5791. sftk_Decrement(ulOperationStateLen,sizeof(SFTKContextType));
  5792. /* get the mechanism structure */
  5793. PORT_Memcpy(&mech.mechanism,pOperationState,sizeof(CK_MECHANISM_TYPE));
  5794. pOperationState += sizeof(CK_MECHANISM_TYPE);
  5795. sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE));
  5796. /* should be filled in... but not necessary for hash */
  5797. mech.pParameter = NULL;
  5798. mech.ulParameterLen = 0;
  5799. switch (type) {
  5800. case SFTK_HASH:
  5801. crv = NSC_DigestInit(hSession,&mech);
  5802. if (crv != CKR_OK) break;
  5803. crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE,
  5804. NULL);
  5805. if (crv != CKR_OK) break;
  5806. PORT_Memcpy(context->cipherInfo,pOperationState,
  5807. context->cipherInfoLen);
  5808. pOperationState += context->cipherInfoLen;
  5809. sftk_Decrement(ulOperationStateLen,context->cipherInfoLen);
  5810. break;
  5811. default:
  5812. /* do sign/encrypt/decrypt later */
  5813. crv = CKR_SAVED_STATE_INVALID;
  5814. }
  5815. sftk_FreeSession(session);
  5816. if (crv != CKR_OK) break;
  5817. }
  5818. return crv;
  5819. }
  5820. /* Dual-function cryptographic operations */
  5821. /* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption
  5822. * operation. */
  5823. CK_RV NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
  5824. CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
  5825. CK_ULONG_PTR pulEncryptedPartLen)
  5826. {
  5827. CK_RV crv;
  5828. CHECK_FORK();
  5829. crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart,
  5830. pulEncryptedPartLen);
  5831. if (crv != CKR_OK) return crv;
  5832. crv = NSC_DigestUpdate(hSession,pPart,ulPartLen);
  5833. return crv;
  5834. }
  5835. /* NSC_DecryptDigestUpdate continues a multiple-part decryption and
  5836. * digesting operation. */
  5837. CK_RV NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
  5838. CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
  5839. CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
  5840. {
  5841. CK_RV crv;
  5842. CHECK_FORK();
  5843. crv = NSC_DecryptUpdate(hSession,pEncryptedPart, ulEncryptedPartLen,
  5844. pPart, pulPartLen);
  5845. if (crv != CKR_OK) return crv;
  5846. crv = NSC_DigestUpdate(hSession,pPart,*pulPartLen);
  5847. return crv;
  5848. }
  5849. /* NSC_SignEncryptUpdate continues a multiple-part signing and
  5850. * encryption operation. */
  5851. CK_RV NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
  5852. CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
  5853. CK_ULONG_PTR pulEncryptedPartLen)
  5854. {
  5855. CK_RV crv;
  5856. CHECK_FORK();
  5857. crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart,
  5858. pulEncryptedPartLen);
  5859. if (crv != CKR_OK) return crv;
  5860. crv = NSC_SignUpdate(hSession,pPart,ulPartLen);
  5861. return crv;
  5862. }
  5863. /* NSC_DecryptVerifyUpdate continues a multiple-part decryption
  5864. * and verify operation. */
  5865. CK_RV NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
  5866. CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
  5867. CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
  5868. {
  5869. CK_RV crv;
  5870. CHECK_FORK();
  5871. crv = NSC_DecryptUpdate(hSession,pEncryptedData, ulEncryptedDataLen,
  5872. pData, pulDataLen);
  5873. if (crv != CKR_OK) return crv;
  5874. crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);
  5875. return crv;
  5876. }
  5877. /* NSC_DigestKey continues a multi-part message-digesting operation,
  5878. * by digesting the value of a secret key as part of the data already digested.
  5879. */
  5880. CK_RV NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
  5881. {
  5882. SFTKSession *session = NULL;
  5883. SFTKObject *key = NULL;
  5884. SFTKAttribute *att;
  5885. CK_RV crv;
  5886. CHECK_FORK();
  5887. session = sftk_SessionFromHandle(hSession);
  5888. if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
  5889. key = sftk_ObjectFromHandle(hKey,session);
  5890. sftk_FreeSession(session);
  5891. if (key == NULL) return CKR_KEY_HANDLE_INVALID;
  5892. /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */
  5893. /* make sure it's a valid key for this operation */
  5894. if (key->objclass != CKO_SECRET_KEY) {
  5895. sftk_FreeObject(key);
  5896. return CKR_KEY_TYPE_INCONSISTENT;
  5897. }
  5898. /* get the key value */
  5899. att = sftk_FindAttribute(key,CKA_VALUE);
  5900. sftk_FreeObject(key);
  5901. if (!att) {
  5902. return CKR_KEY_HANDLE_INVALID;
  5903. }
  5904. crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue,
  5905. att->attrib.ulValueLen);
  5906. sftk_FreeAttribute(att);
  5907. return crv;
  5908. }