Commit 374804bd authored by Pauli's avatar Pauli
Browse files

Key zeroization fix for EVP_SealInit.



Manual backport from master.

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7116)
parent bfd752fe
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
@@ -21,6 +21,7 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
{
    unsigned char key[EVP_MAX_KEY_LENGTH];
    int i;
    int rv = 0;

    if (type) {
        EVP_CIPHER_CTX_reset(ctx);
@@ -31,21 +32,27 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
        return 1;
    if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
        return 0;

    if (EVP_CIPHER_CTX_iv_length(ctx)
            && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0)
        return 0;
        goto err;

    if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
        return 0;
        goto err;

    for (i = 0; i < npubk; i++) {
        ekl[i] =
            EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx),
                                 pubk[i]);
        if (ekl[i] <= 0)
            return (-1);
        if (ekl[i] <= 0) {
            rv = -1;
            goto err;
        }
    }
    return (npubk);
    rv = npubk;
err:
    OPENSSL_cleanse(key, sizeof(key));
    return rv;
}

/*- MACRO
+47 −1
Original line number Diff line number Diff line
/*
 * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
@@ -9,6 +9,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
@@ -326,6 +327,46 @@ static int test_d2i_AutoPrivateKey(const unsigned char *input,
    return ret;
}

static int test_EVP_Enveloped(void)
{
    int ret = 0;
    EVP_CIPHER_CTX *ctx = NULL;
    EVP_PKEY *keypair = NULL;
    unsigned char *kek = NULL;
    int kek_len;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    static const unsigned char msg[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    int len, ciphertext_len, plaintext_len;
    unsigned char ciphertext[32], plaintext[16];
    const EVP_CIPHER *type = EVP_aes_256_cbc();

    if ((keypair = load_example_rsa_key()) == NULL
            || (kek = OPENSSL_zalloc(EVP_PKEY_size(keypair))) == NULL
            || (ctx = EVP_CIPHER_CTX_new()) == NULL
            || !EVP_SealInit(ctx, type, &kek, &kek_len, iv, &keypair, 1)
            || !EVP_SealUpdate(ctx, ciphertext, &ciphertext_len,
                               msg, sizeof(msg))
            || !EVP_SealFinal(ctx, ciphertext + ciphertext_len, &len))
        goto err;

    ciphertext_len += len;
    if (!EVP_OpenInit(ctx, type, kek, kek_len, iv, keypair)
            || !EVP_OpenUpdate(ctx, plaintext, &plaintext_len,
                               ciphertext, ciphertext_len)
            || !EVP_OpenFinal(ctx, plaintext + plaintext_len, &len)
            || (plaintext_len += len) != sizeof(msg)
            || memcmp(msg, plaintext, sizeof(msg)) != 0)
        goto err;

    ret = 1;

err:
    OPENSSL_free(kek);
    EVP_PKEY_free(keypair);
    EVP_CIPHER_CTX_free(ctx);
    return ret;
}

#ifndef OPENSSL_NO_EC
/* Tests loading a bad key in PKCS8 format */
static int test_EVP_PKCS82PKEY(void)
@@ -386,6 +427,11 @@ int main(void)
        return 1;
    }

    if (!test_EVP_Enveloped()) {
        fprintf(stderr, "test_EVP_Enveloped failed\n");
        return 1;
    }

#ifndef OPENSSL_NO_EC
    if (!test_d2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
                                 EVP_PKEY_EC)) {