static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { EC_PKEY_CTX *dctx = ctx->data; unsigned char *ktmp = NULL; size_t ktmplen; int rv = 0; if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE) return pkey_ec_derive(ctx, key, keylen); if (!key) { *keylen = dctx->kdf_outlen; return 1; } if (*keylen != dctx->kdf_outlen) return 0; if (!pkey_ec_derive(ctx, NULL, &ktmplen)) return 0; ktmp = OPENSSL_malloc(ktmplen); if (ktmp == NULL) return 0; if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) goto err; /* Do KDF stuff */ if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen, dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) goto err; rv = 1; err: OPENSSL_clear_free(ktmp, ktmplen); return rv; }
static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen) { EC_PKEY_CTX *dctx = ctx->data; uint8_t *ktmp = NULL; size_t ktmplen; int rv = 0; if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE) return pkey_ec_derive(ctx, key, keylen); if (key == NULL) { *keylen = dctx->kdf_outlen; return 1; } if (*keylen != dctx->kdf_outlen) return 0; if (!pkey_ec_derive(ctx, NULL, &ktmplen)) return 0; ktmp = malloc(ktmplen); if (ktmp == NULL) return 0; if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) goto err; /* Do KDF stuff */ if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen, dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) goto err; rv = 1; err: vigortls_zeroize(ktmp, ktmplen); free(ktmp); return rv; }