static int generate_random_key(TALLOC_CTX *mem_ctx, PK11SlotInfo *slot, struct crypto_mech_data *mech_props, SECItem **_key) { SECStatus sret; SECItem *randkeydata; SECItem *key = NULL; PK11SymKey *randkey; int ret; randkey = PK11_KeyGen(slot, mech_props->cipher, NULL, mech_props->keylen, NULL); if (randkey == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to generate key (err %d)\n", PR_GetError()); ret = EIO; goto done; } sret = PK11_ExtractKeyValue(randkey); if (sret != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to extract key value (err %d)\n", PR_GetError()); ret = EIO; goto done; } randkeydata = PK11_GetKeyData(randkey); if (randkeydata == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to get key data (err %d)\n", PR_GetError()); ret = EIO; goto done; } /* randkeydata is valid until randkey is. Copy with talloc to * get a nice memory hierarchy symmetrical in encrypt * and decrypt case */ key = talloc_zero(mem_ctx, SECItem); if (!key) { ret = ENOMEM; goto done; } key->data = talloc_memdup(key, randkeydata->data, randkeydata->len); if (!key->data) { ret = ENOMEM; goto done; } key->len = randkeydata->len; *_key = key; ret = EOK; done: if (ret != EOK) talloc_zfree(key); PK11_FreeSymKey(randkey); return ret; }
static SECStatus ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp) { SECStatus rv; PK11SymKey * ms = NULL; SECItem params = {siBuffer, NULL, 0}; CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; unsigned char rand[SSL3_RANDOM_LENGTH]; CK_VERSION pms_version; CK_MECHANISM_TYPE master_derive; CK_MECHANISM_TYPE key_derive; CK_FLAGS keyFlags; if (pms == NULL) return(SECFailure); PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH); if (isTLS) { if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; else master_derive = CKM_TLS_MASTER_KEY_DERIVE; key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; keyFlags = CKF_SIGN | CKF_VERIFY; } else { if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH; else master_derive = CKM_SSL3_MASTER_KEY_DERIVE; key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; keyFlags = 0; } master_params.pVersion = &pms_version; master_params.RandomInfo.pClientRandom = rand; master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; master_params.RandomInfo.pServerRandom = rand; master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; params.data = (unsigned char *) &master_params; params.len = sizeof master_params; ms = PK11_DeriveWithFlags(pms, master_derive, ¶ms, key_derive, CKA_DERIVE, 0, keyFlags); if (ms == NULL) return(SECFailure); rv = PK11_ExtractKeyValue(ms); *pcbp = (rv == SECSuccess); PK11_FreeSymKey(ms); return(rv); }
void ssl_PrintKey(sslSocket *ss, const char *msg, PK11SymKey *key) { SECStatus rv; SECItem *rawkey; rv = PK11_ExtractKeyValue(key); if (rv != SECSuccess) { ssl_Trace("Could not extract key for %s", msg); return; } rawkey = PK11_GetKeyData(key); if (!rawkey) { ssl_Trace("Could not extract key for %s", msg); return; } ssl_PrintBuf(ss, msg, rawkey->data, rawkey->len); }
SECStatus tls13_HkdfExpandLabelRaw(PK11SymKey *prk, SSLHashType baseHash, const PRUint8 *handshakeHash, unsigned int handshakeHashLen, const char *label, unsigned int labelLen, unsigned char *output, unsigned int outputLen) { PK11SymKey *derived = NULL; SECItem *rawkey; SECStatus rv; rv = tls13_HkdfExpandLabel(prk, baseHash, handshakeHash, handshakeHashLen, label, labelLen, kTlsHkdfInfo[baseHash].pkcs11Mech, outputLen, &derived); if (rv != SECSuccess || !derived) { goto abort; } rv = PK11_ExtractKeyValue(derived); if (rv != SECSuccess) { goto abort; } rawkey = PK11_GetKeyData(derived); if (!rawkey) { goto abort; } PORT_Assert(rawkey->len == outputLen); memcpy(output, rawkey->data, outputLen); PK11_FreeSymKey(derived); return SECSuccess; abort: if (derived) { PK11_FreeSymKey(derived); } PORT_SetError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE); return SECFailure; }
void PrintKey(PK11SymKey *symKey) { char *name = PK11_GetSymKeyNickname(symKey); int len = PK11_GetKeyLength(symKey); int strength = PK11_GetKeyStrength(symKey, NULL); SECItem *value = NULL; CK_KEY_TYPE type = PK11_GetSymKeyType(symKey); (void) PK11_ExtractKeyValue(symKey); value = PK11_GetKeyData(symKey); printf("%-20s %3d %4d %10s ", name ? name: " ", len, strength, GetStringFromKeyType(type)); if (value && value->data) { printBuf(value->data, value->len); } else { printf("<restricted>"); } printf("\n"); }
void nss_symkey_log(PK11SymKey *key, const char *msg) { if (key != NULL) { DBG(DBG_CRYPT, DBG_log("computed key %s with length =%d", msg, PK11_GetKeyLength(key))); } else { DBG_log("NULL key %s", msg); } if (!PK11_IsFIPS()) { if (key != NULL) { SECStatus status = PK11_ExtractKeyValue(key); PR_ASSERT(status == SECSuccess); SECItem *keydata = PK11_GetKeyData(key); DBG(DBG_CRYPT, DBG_dump("value: ", keydata->data, keydata->len)); /* SECITEM_FreeItem(keydata, PR_TRUE); */ } } }
static void do_serpent(u_int8_t *buf, size_t buf_size, PK11SymKey *key, u_int8_t *iv, bool enc) { serpent_context serpent_ctx; u_int8_t iv_bak[SERPENT_CBC_BLOCK_SIZE]; u_int8_t *new_iv = buf + buf_size - SERPENT_CBC_BLOCK_SIZE; u_int8_t *bare_key_ptr; size_t bare_key_len; /* unpack key from PK11SymKey (or crash!) */ { SECStatus status = PK11_ExtractKeyValue(key); SECItem *keydata; passert(status == SECSuccess); keydata = PK11_GetKeyData(key); bare_key_ptr = keydata->data; bare_key_len = keydata->len; // SECITEM_FreeItem(keydata, PR_TRUE); } serpent_set_key(&serpent_ctx, bare_key_ptr, bare_key_len); /* * my SERPENT cbc does not touch passed IV (optimization for * ESP handling), so I must "emulate" des-like IV * crunching */ if (!enc) { memcpy(iv_bak, new_iv, SERPENT_CBC_BLOCK_SIZE); new_iv = iv_bak; } serpent_cbc_encrypt(&serpent_ctx, buf, buf, buf_size, iv, enc); memcpy(iv, new_iv, SERPENT_CBC_BLOCK_SIZE); }
SECStatus tls13_HkdfExtract(PK11SymKey *ikm1, PK11SymKey *ikm2in, SSLHashType baseHash, PK11SymKey **prkp) { CK_NSS_HKDFParams params; SECItem paramsi; SECStatus rv; SECItem *salt; PK11SymKey *prk; static const PRUint8 zeroKeyBuf[HASH_LENGTH_MAX]; PK11SymKey *zeroKey = NULL; PK11SlotInfo *slot = NULL; PK11SymKey *ikm2; params.bExtract = CK_TRUE; params.bExpand = CK_FALSE; params.pInfo = NULL; params.ulInfoLen = 0UL; if (ikm1) { /* TODO([email protected]): This violates the PKCS#11 key boundary * but is imposed on us by the present HKDF interface. */ rv = PK11_ExtractKeyValue(ikm1); if (rv != SECSuccess) return rv; salt = PK11_GetKeyData(ikm1); if (!salt) return SECFailure; params.pSalt = salt->data; params.ulSaltLen = salt->len; PORT_Assert(salt->len > 0); } else { /* Per documentation for CKM_NSS_HKDF_*: * * If the optional salt is given, it is used; otherwise, the salt is * set to a sequence of zeros equal in length to the HMAC output. */ params.pSalt = NULL; params.ulSaltLen = 0UL; } paramsi.data = (unsigned char *)¶ms; paramsi.len = sizeof(params); PORT_Assert(kTlsHkdfInfo[baseHash].pkcs11Mech); PORT_Assert(kTlsHkdfInfo[baseHash].hashSize); PORT_Assert(kTlsHkdfInfo[baseHash].hash == baseHash); /* A zero ikm2 is a key of hash-length 0s. */ if (!ikm2in) { SECItem zeroItem = { siBuffer, (unsigned char *)zeroKeyBuf, kTlsHkdfInfo[baseHash].hashSize }; slot = PK11_GetInternalSlot(); if (!slot) { return SECFailure; } zeroKey = PK11_ImportSymKey(slot, kTlsHkdfInfo[baseHash].pkcs11Mech, PK11_OriginUnwrap, CKA_DERIVE, &zeroItem, NULL); if (!zeroKey) return SECFailure; ikm2 = zeroKey; } else { ikm2 = ikm2in; } PORT_Assert(ikm2); PRINT_BUF(50, (NULL, "HKDF Extract: IKM1/Salt", params.pSalt, params.ulSaltLen)); PRINT_KEY(50, (NULL, "HKDF Extract: IKM2", ikm2)); prk = PK11_Derive(ikm2, kTlsHkdfInfo[baseHash].pkcs11Mech, ¶msi, kTlsHkdfInfo[baseHash].pkcs11Mech, CKA_DERIVE, kTlsHkdfInfo[baseHash].hashSize); if (zeroKey) PK11_FreeSymKey(zeroKey); if (slot) PK11_FreeSlot(slot); if (!prk) return SECFailure; PRINT_KEY(50, (NULL, "HKDF Extract", prk)); *prkp = prk; return SECSuccess; }
static gchar* cipher_pbkdf2_nss_sha1(const gchar *passphrase, const gchar *salt, guint iter_count, guint out_len) { PK11SlotInfo *slot; SECAlgorithmID *algorithm = NULL; PK11SymKey *symkey = NULL; const SECItem *symkey_data = NULL; SECItem salt_item, passphrase_item; guchar *passphrase_buff, *salt_buff; gchar *ret; g_return_val_if_fail(passphrase != NULL, NULL); g_return_val_if_fail(iter_count > 0, NULL); g_return_val_if_fail(out_len > 0, NULL); NSS_NoDB_Init(NULL); slot = PK11_GetBestSlot(PK11_AlgtagToMechanism(SEC_OID_PKCS5_PBKDF2), NULL); if (slot == NULL) { purple_debug_error("cipher-test", "NSS: couldn't get slot: " "%d\n", PR_GetError()); return NULL; } salt_buff = (guchar*)g_strdup(salt ? salt : ""); salt_item.type = siBuffer; salt_item.data = salt_buff; salt_item.len = salt ? strlen(salt) : 0; algorithm = PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2, SEC_OID_AES_256_CBC, SEC_OID_HMAC_SHA1, out_len, iter_count, &salt_item); if (algorithm == NULL) { purple_debug_error("cipher-test", "NSS: couldn't create " "algorithm ID: %d\n", PR_GetError()); PK11_FreeSlot(slot); g_free(salt_buff); return NULL; } passphrase_buff = (guchar*)g_strdup(passphrase); passphrase_item.type = siBuffer; passphrase_item.data = passphrase_buff; passphrase_item.len = strlen(passphrase); symkey = PK11_PBEKeyGen(slot, algorithm, &passphrase_item, PR_FALSE, NULL); if (symkey == NULL) { purple_debug_error("cipher-test", "NSS: Couldn't generate key: " "%d\n", PR_GetError()); SECOID_DestroyAlgorithmID(algorithm, PR_TRUE); PK11_FreeSlot(slot); g_free(passphrase_buff); g_free(salt_buff); return NULL; } if (PK11_ExtractKeyValue(symkey) == SECSuccess) symkey_data = PK11_GetKeyData(symkey); if (symkey_data == NULL || symkey_data->data == NULL) { purple_debug_error("cipher-test", "NSS: Couldn't extract key " "value: %d\n", PR_GetError()); PK11_FreeSymKey(symkey); SECOID_DestroyAlgorithmID(algorithm, PR_TRUE); PK11_FreeSlot(slot); g_free(passphrase_buff); g_free(salt_buff); return NULL; } if (symkey_data->len != out_len) { purple_debug_error("cipher-test", "NSS: Invalid key length: %d " "(should be %d)\n", symkey_data->len, out_len); PK11_FreeSymKey(symkey); SECOID_DestroyAlgorithmID(algorithm, PR_TRUE); PK11_FreeSlot(slot); g_free(passphrase_buff); g_free(salt_buff); return NULL; } ret = purple_base16_encode(symkey_data->data, symkey_data->len); PK11_FreeSymKey(symkey); SECOID_DestroyAlgorithmID(algorithm, PR_TRUE); PK11_FreeSlot(slot); g_free(passphrase_buff); g_free(salt_buff); return ret; }