*/
#include "ies.h"
-#include <iostream>
+#include <new>
#include <vector>
#define SET_ERROR(string) \
#define SET_OSSL_ERROR(string) \
sprintf(error, "%s {error = %s} %s:%d", (string), ERR_error_string(ERR_get_error(), NULL), __FILE__, __LINE__)
+const size_t nEnvKeyLen = 16 + 20; // EVP_CIPHER_key_length(EVP_aes_128_cbc()) + EVP_MD_size(EVP_ripemd160())
+
/* Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
* Taken from openssl/crypto/ecdh/ech_kdf.c in github:openssl/openssl
* ffa08b3242e0f10f1fef3c93ef3f0b51de8c27a9 */
return rv;
}
-static size_t envelope_key_len(const ies_ctx_t *ctx)
-{
- return EVP_CIPHER_key_length(ctx->cipher) + EVP_MD_size(ctx->md);
-}
-
static EC_KEY * ecies_key_create(const EC_KEY *user, char *error) {
const EC_GROUP *group;
static unsigned char *prepare_envelope_key(const ies_ctx_t *ctx, cryptogram_t *cryptogram, char *error)
{
- const size_t key_buf_len = envelope_key_len(ctx);
const size_t ecdh_key_len = (EC_GROUP_get_degree(EC_KEY_get0_group(ctx->user_key)) + 7) / 8;
unsigned char *envelope_key = NULL, *ktmp = NULL;
EC_KEY *ephemeral = NULL;
/* High-level ECDH via EVP does not allow use of arbitrary KDF function.
* We should use low-level API for KDF2
* c.f. openssl/crypto/ec/ec_pmeth.c */
- if ((envelope_key = (unsigned char *) OPENSSL_malloc(key_buf_len)) == NULL) {
+ if ((envelope_key = (unsigned char *) OPENSSL_malloc(nEnvKeyLen)) == NULL) {
SET_ERROR("Failed to allocate memory for envelope_key");
goto err;
}
}
/* equals to ISO 18033-2 KDF2 */
- if (!ECDH_KDF_X9_62(envelope_key, key_buf_len, ktmp, ecdh_key_len, 0, 0, ctx->kdf_md)) {
+ if (!ECDH_KDF_X9_62(envelope_key, nEnvKeyLen, ktmp, ecdh_key_len, 0, 0, ctx->kdf_md)) {
SET_OSSL_ERROR("Failed to stretch with KDF2");
goto err;
}
if (ephemeral)
EC_KEY_free(ephemeral);
if (envelope_key) {
- OPENSSL_cleanse(envelope_key, key_buf_len);
+ OPENSSL_cleanse(envelope_key, nEnvKeyLen);
OPENSSL_free(envelope_key);
}
if (ktmp) {
goto err;
}
- OPENSSL_cleanse(envelope_key, envelope_key_len(ctx));
+ OPENSSL_cleanse(envelope_key, nEnvKeyLen);
OPENSSL_free(envelope_key);
return cryptogram;
if (cryptogram)
cryptogram_free(cryptogram);
if (envelope_key) {
- OPENSSL_cleanse(envelope_key, envelope_key_len(ctx));
+ OPENSSL_cleanse(envelope_key, nEnvKeyLen);
OPENSSL_free(envelope_key);
}
return NULL;
unsigned char *restore_envelope_key(const ies_ctx_t *ctx, const cryptogram_t *cryptogram, char *error)
{
- const size_t key_buf_len = envelope_key_len(ctx);
const size_t ecdh_key_len = (EC_GROUP_get_degree(EC_KEY_get0_group(ctx->user_key)) + 7) / 8;
EC_KEY *ephemeral = NULL, *user_copy = NULL;
unsigned char *envelope_key = NULL, *ktmp = NULL;
- if ((envelope_key = (unsigned char *) OPENSSL_malloc(key_buf_len)) == NULL) {
+ if ((envelope_key = (unsigned char *) OPENSSL_malloc(nEnvKeyLen)) == NULL) {
SET_ERROR("Failed to allocate memory for envelope_key");
goto err;
}
}
/* equals to ISO 18033-2 KDF2 */
- if (!ECDH_KDF_X9_62(envelope_key, key_buf_len, ktmp, ecdh_key_len, 0, 0, ctx->kdf_md)) {
+ if (!ECDH_KDF_X9_62(envelope_key, nEnvKeyLen, ktmp, ecdh_key_len, 0, 0, ctx->kdf_md)) {
SET_OSSL_ERROR("Failed to stretch with KDF2");
goto err;
}
if (user_copy)
EC_KEY_free(user_copy);
if (envelope_key) {
- OPENSSL_cleanse(envelope_key, key_buf_len);
+ OPENSSL_cleanse(envelope_key, nEnvKeyLen);
OPENSSL_free(envelope_key);
}
if (ktmp) {
}
err:
- OPENSSL_cleanse(envelope_key, envelope_key_len(ctx));
+ OPENSSL_cleanse(envelope_key, nEnvKeyLen);
OPENSSL_free(envelope_key);
return output;