Mercurial > dovecot > core-2.3
changeset 26370:5ca41ccc08ce
lib-dcrypt: Move shared secret derivation to dcrypt_openssl_echd_derive_secret
Makes it possible to expose it on next commit.
author | Aki Tuomi <aki.tuomi@open-xchange.com> |
---|---|
date | Thu, 29 Aug 2019 16:43:45 +0300 |
parents | c558e7a951e0 |
children | 1d6ed0246396 |
files | src/lib-dcrypt/dcrypt-openssl.c |
diffstat | 1 files changed, 54 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-dcrypt/dcrypt-openssl.c Thu Aug 29 16:52:51 2019 +0300 +++ b/src/lib-dcrypt/dcrypt-openssl.c Thu Aug 29 16:43:45 2019 +0300 @@ -721,10 +721,44 @@ } static bool +dcrypt_openssl_ecdh_derive_secret(struct dcrypt_private_key *priv_key, + struct dcrypt_public_key *pub_key, + buffer_t *shared_secret, + const char **error_r) +{ + /* initialize */ + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(priv_key->key, NULL); + if (pctx == NULL || + EVP_PKEY_derive_init(pctx) != 1 || + EVP_PKEY_derive_set_peer(pctx, pub_key->key) != 1) { + EVP_PKEY_CTX_free(pctx); + return dcrypt_openssl_error(error_r); + } + + /* derive */ + size_t len; + if (EVP_PKEY_derive(pctx, NULL, &len) != 1) { + EVP_PKEY_CTX_free(pctx); + return dcrypt_openssl_error(error_r); + } + unsigned char buf[len]; + if (EVP_PKEY_derive(pctx, buf, &len) != 1) { + EVP_PKEY_CTX_free(pctx); + return dcrypt_openssl_error(error_r); + } + + EVP_PKEY_CTX_free(pctx); + buffer_append(shared_secret, buf, len); + + return TRUE; +} + +static bool dcrypt_openssl_ecdh_derive_secret_local(struct dcrypt_private_key *local_key, buffer_t *R, buffer_t *S, const char **error_r) { + bool ret; i_assert(local_key != NULL && local_key->key != NULL); EVP_PKEY *local = local_key->key; @@ -769,36 +803,15 @@ } EVP_PKEY_set1_EC_KEY(peer, ec_key); EC_KEY_free(ec_key); - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(local, NULL); - - /* initialize derivation */ - if (pctx == NULL || - EVP_PKEY_derive_init(pctx) != 1 || - EVP_PKEY_derive_set_peer(pctx, peer) != 1) { - EVP_PKEY_CTX_free(pctx); - EVP_PKEY_free(peer); - return dcrypt_openssl_error(error_r); - } - - /* have to do it twice to get the data length */ - size_t len; - if (EVP_PKEY_derive(pctx, NULL, &len) != 1) { - EVP_PKEY_CTX_free(pctx); - EVP_PKEY_free(peer); - return dcrypt_openssl_error(error_r); - } - - unsigned char buf[len]; - memset(buf,0,len); - if (EVP_PKEY_derive(pctx, buf, &len) != 1) { - EVP_PKEY_CTX_free(pctx); - EVP_PKEY_free(peer); - return dcrypt_openssl_error(error_r); - } - EVP_PKEY_CTX_free(pctx); - buffer_append(S, buf, len); + + struct dcrypt_public_key pub_key; + i_zero(&pub_key); + pub_key.key = peer; + + ret = dcrypt_openssl_ecdh_derive_secret(local_key, &pub_key, S, error_r); + EVP_PKEY_free(peer); - return TRUE; + return ret; } static bool @@ -807,6 +820,7 @@ const char **error_r) { i_assert(peer_key != NULL && peer_key->key != NULL); + bool ret; /* ensure peer_key is EC key */ EVP_PKEY *local = NULL; @@ -823,36 +837,22 @@ if (!dcrypt_openssl_generate_ec_key(nid, &local, error_r)) return FALSE; - /* initialize */ - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(local, NULL); - if (pctx == NULL || - EVP_PKEY_derive_init(pctx) != 1 || - EVP_PKEY_derive_set_peer(pctx, peer) != 1) { - EVP_PKEY_CTX_free(pctx); - return dcrypt_openssl_error(error_r); + struct dcrypt_private_key priv_key; + i_zero(&priv_key); + priv_key.key = local; + + if (!(ret = dcrypt_openssl_ecdh_derive_secret(&priv_key, peer_key, S, + error_r))) { + EVP_PKEY_free(local); + return FALSE; } - /* derive */ - size_t len; - if (EVP_PKEY_derive(pctx, NULL, &len) != 1) { - EVP_PKEY_CTX_free(pctx); - return dcrypt_openssl_error(error_r); - } - unsigned char buf[len]; - if (EVP_PKEY_derive(pctx, buf, &len) != 1) { - EVP_PKEY_CTX_free(pctx); - return dcrypt_openssl_error(error_r); - } - - EVP_PKEY_CTX_free(pctx); - buffer_append(S, buf, len); - /* get ephemeral key (=R) */ BN_CTX *bn_ctx = BN_CTX_new(); const EC_POINT *pub = EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(local)); const EC_GROUP *grp = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(local)); - len = EC_POINT_point2oct(grp, pub, POINT_CONVERSION_COMPRESSED, - NULL, 0, bn_ctx); + size_t len = EC_POINT_point2oct(grp, pub, POINT_CONVERSION_COMPRESSED, + NULL, 0, bn_ctx); unsigned char R_buf[len]; EC_POINT_point2oct(grp, pub, POINT_CONVERSION_COMPRESSED, R_buf, len, bn_ctx); @@ -860,7 +860,7 @@ buffer_append(R, R_buf, len); EVP_PKEY_free(local); - return TRUE; + return ret; } static bool