SECStatus EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams) { PLArenaPool *arena; ECParams *params; SECStatus rv = SECFailure; /* Initialize an arena for the ECParams structure */ if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE))) return SECFailure; params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams)); if (!params) { PORT_FreeArena(arena, PR_TRUE); return SECFailure; } /* Copy the encoded params */ SECITEM_AllocItem(arena, &(params->DEREncoding), encodedParams->len); memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len); /* Fill out the rest of the ECParams structure based on * the encoded params */ rv = EC_FillParams(arena, encodedParams, params); if (rv == SECFailure) { PORT_FreeArena(arena, PR_TRUE); return SECFailure; } else { *ecparams = params; ; return SECSuccess; } }
SECStatus ectest_ecdh_kat(ECDH_KAT *kat) { ECCurveName curve = kat->curve; ECParams ecParams = { 0 }; ECPrivateKey *ecPriv = NULL; SECItem theirKey = { siBuffer, NULL, 0 }; SECStatus rv = SECFailure; PLArenaPool *arena = NULL; SECItem seed = { siBuffer, NULL, 0 }; SECItem answer = { siBuffer, NULL, 0 }; SECItem answer2 = { siBuffer, NULL, 0 }; SECItem derived = { siBuffer, NULL, 0 }; SECItem ecEncodedParams = { siBuffer, NULL, 0 }; int i; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { return SECFailure; } rv = SECU_ecName2params(curve, &ecEncodedParams); if (rv != SECSuccess) { goto cleanup; } EC_FillParams(arena, &ecEncodedParams, &ecParams); if (kat->our_pubhex) { SECU_HexString2SECItem(arena, &answer, kat->our_pubhex); } SECU_HexString2SECItem(arena, &seed, kat->privhex); rv = EC_NewKeyFromSeed(&ecParams, &ecPriv, seed.data, seed.len); if (rv != SECSuccess) { rv = SECFailure; goto cleanup; } if (kat->our_pubhex) { if (SECITEM_CompareItem(&answer, &ecPriv->publicValue) != SECEqual) { rv = SECFailure; goto cleanup; } } SECU_HexString2SECItem(arena, &theirKey, kat->their_pubhex); SECU_HexString2SECItem(arena, &answer2, kat->common_key); rv = EC_ValidatePublicKey(&ecParams, &theirKey); if (rv != SECSuccess) { printf("EC_ValidatePublicKey failed\n"); goto cleanup; } for (i = 0; i < kat->iterations; ++i) { rv = ECDH_Derive(&theirKey, &ecParams, &ecPriv->privateValue, PR_TRUE, &derived); if (rv != SECSuccess) { rv = SECFailure; goto cleanup; } rv = SECITEM_CopyItem(ecParams.arena, &theirKey, &ecPriv->privateValue); if (rv != SECSuccess) { goto cleanup; } rv = SECITEM_CopyItem(ecParams.arena, &ecPriv->privateValue, &derived); if (rv != SECSuccess) { goto cleanup; } SECITEM_FreeItem(&derived, PR_FALSE); } if (SECITEM_CompareItem(&answer2, &ecPriv->privateValue) != SECEqual) { printf("expected: "); printBuf(&answer2); printf("derived: "); printBuf(&ecPriv->privateValue); rv = SECFailure; goto cleanup; } cleanup: SECITEM_FreeItem(&ecEncodedParams, PR_FALSE); PORT_FreeArena(arena, PR_FALSE); if (ecPriv) { PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE); } if (derived.data) { SECITEM_FreeItem(&derived, PR_FALSE); } return rv; }