/* * Given a hex encoded string, decode it into a chunk. * * If this function fails, crash and burn. It is fed static data * so should never ever have a problem. * The caller must free the chunk. */ chunk_t decode_hex_to_chunk(const char *original, const char *string) { /* The decoded buffer can't be bigger than half the encoded string. */ chunk_t chunk = zalloc_chunk((strlen(string)+1)/2, original); chunk.len = 0; const char *pos = string; for (;;) { /* skip leading/trailing space */ while (*pos == ' ') { pos++; } if (*pos == '\0') { break; } /* Expecting <HEX><HEX> */ char buf[3] = { '\0', '\0', '\0' }; if (isxdigit(*pos)) { buf[0] = *pos++; if (isxdigit(*pos)) { buf[1] = *pos++; } } if (buf[1] == '\0') { PASSERT_FAIL("expected hex digit at offset %tu in hex buffer \"%s\" but found \"%.1s\"", pos - string, string, pos); } char *end; chunk.ptr[chunk.len] = strtoul(buf, &end, 16); passert(*end == '\0'); chunk.len++; } return chunk; }
static void nss_ecp_calc_secret(const struct dh_desc *group, SECKEYPrivateKey **privk, SECKEYPublicKey **pubk, uint8_t *ke, size_t sizeof_ke) { passert(sizeof_ke == group->bytes); /* * Get the PK11 formatted EC parameters (stored in static * data) from NSS. */ DBG(DBG_CRYPT, DBG_log("oid %d %x", group->nss_oid, group->nss_oid)); SECOidData *pk11_data = SECOID_FindOIDByTag(group->nss_oid); if (pk11_data == NULL) { PASSERT_FAIL("Lookup of OID %d for EC group %s parameters failed", group->nss_oid, group->common.name); } LSWDBGP(DBG_CRYPT, buf) { lswlogs(buf, "pk11_data->oid: "); lswlog_nss_secitem(buf, &pk11_data->oid); }
static void ike_alg_nss_cbc(const struct encrypt_desc *alg, u_int8_t *in_buf, size_t in_buf_len, PK11SymKey *symkey, u_int8_t *iv, bool enc) { DBG(DBG_CRYPT, DBG_log("NSS ike_alg_nss_cbc: %s - enter", alg->common.name)); if (symkey == NULL) { PASSERT_FAIL("%s - NSS derived enc key in NULL", alg->common.name); } SECItem ivitem; ivitem.type = siBuffer; ivitem.data = iv; ivitem.len = alg->enc_blocksize; SECItem *secparam = PK11_ParamFromIV(alg->common.nss_mechanism, &ivitem); if (secparam == NULL) { PASSERT_FAIL("%s - Failure to set up PKCS11 param (err %d)", alg->common.name, PR_GetError()); } PK11Context *enccontext; enccontext = PK11_CreateContextBySymKey(alg->common.nss_mechanism, enc ? CKA_ENCRYPT : CKA_DECRYPT, symkey, secparam); if (enccontext == NULL) { PASSERT_FAIL("%s - PKCS11 context creation failure (err %d)", alg->common.name, PR_GetError()); } /* Output buffer for transformed data. */ u_int8_t *out_buf = PR_Malloc((PRUint32)in_buf_len); int out_buf_len = 0; SECStatus rv = PK11_CipherOp(enccontext, out_buf, &out_buf_len, in_buf_len, in_buf, in_buf_len); if (rv != SECSuccess) { PASSERT_FAIL("%s - PKCS11 operation failure (err %d)", alg->common.name, PR_GetError()); } PK11_DestroyContext(enccontext, PR_TRUE); /* * Update the IV ready for the next call to this function. */ u_int8_t *new_iv; if (enc) { /* * The IV for the next encryption call is the last * block of encrypted output data. */ new_iv = out_buf + out_buf_len - alg->enc_blocksize; } else { /* * The IV for the next decryption call is the last * block of the encrypted input data. */ new_iv = in_buf + in_buf_len - alg->enc_blocksize; } memcpy(iv, new_iv, alg->enc_blocksize); /* * Finally, copy the transformed data back to the buffer. Do * this after extracting the IV. */ memcpy(in_buf, out_buf, in_buf_len); PR_Free(out_buf); if (secparam != NULL) SECITEM_FreeItem(secparam, PR_TRUE); DBG(DBG_CRYPT, DBG_log("NSS ike_alg_nss_cbc: %s - exit", alg->common.name)); }