Blame test/dsa_no_digest_size_test.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
 * this file except in compliance with the License.  You can obtain a copy
Packit c4476c
 * in the file LICENSE in the source distribution or at
Packit c4476c
 * https://www.openssl.org/source/license.html
Packit c4476c
 */
Packit c4476c
Packit c4476c
#include <stdlib.h>
Packit c4476c
#include <string.h>
Packit c4476c
Packit c4476c
#include "testutil.h"
Packit c4476c
Packit c4476c
#include <openssl/evp.h>
Packit c4476c
#include <openssl/err.h>
Packit c4476c
#include <openssl/rand.h>
Packit c4476c
Packit c4476c
#ifndef OPENSSL_NO_DSA
Packit c4476c
#include <openssl/dsa.h>
Packit c4476c
Packit c4476c
static DSA *dsakey;
Packit c4476c
Packit c4476c
/*
Packit c4476c
 * These parameters are from test/recipes/04-test_pem_data/dsaparam.pem,
Packit c4476c
 * converted using dsaparam -C
Packit c4476c
 */
Packit c4476c
static DSA *load_dsa_params(void)
Packit c4476c
{
Packit c4476c
    static unsigned char dsap_2048[] = {
Packit c4476c
        0xAE, 0x35, 0x7D, 0x4E, 0x1D, 0x96, 0xE2, 0x9F, 0x00, 0x96,
Packit c4476c
        0x60, 0x5A, 0x6E, 0x4D, 0x07, 0x8D, 0xA5, 0x7C, 0xBC, 0xF9,
Packit c4476c
        0xAD, 0xD7, 0x9F, 0xD5, 0xE9, 0xEE, 0xA6, 0x33, 0x51, 0xDE,
Packit c4476c
        0x7B, 0x72, 0xD2, 0x75, 0xAA, 0x71, 0x77, 0xF1, 0x63, 0xFB,
Packit c4476c
        0xB6, 0xEC, 0x5A, 0xBA, 0x0D, 0x72, 0xA2, 0x1A, 0x1C, 0x64,
Packit c4476c
        0xB8, 0xE5, 0x89, 0x09, 0x6D, 0xC9, 0x6F, 0x0B, 0x7F, 0xD2,
Packit c4476c
        0xCE, 0x9F, 0xEF, 0x87, 0x5A, 0xB6, 0x67, 0x2F, 0xEF, 0xEE,
Packit c4476c
        0xEB, 0x59, 0xF5, 0x5E, 0xFF, 0xA8, 0x28, 0x84, 0x9E, 0x5B,
Packit c4476c
        0x37, 0x09, 0x11, 0x80, 0x7C, 0x08, 0x5C, 0xD5, 0xE1, 0x48,
Packit c4476c
        0x4B, 0xD2, 0x68, 0xFB, 0x3F, 0x9F, 0x2B, 0x6B, 0x6C, 0x0D,
Packit c4476c
        0x48, 0x1B, 0x1A, 0x80, 0xC2, 0xEB, 0x11, 0x1B, 0x37, 0x79,
Packit c4476c
        0xD6, 0x8C, 0x8B, 0x72, 0x3E, 0x67, 0xA5, 0x05, 0x0E, 0x41,
Packit c4476c
        0x8A, 0x9E, 0x35, 0x50, 0xB4, 0xD2, 0x40, 0x27, 0x6B, 0xFD,
Packit c4476c
        0xE0, 0x64, 0x6B, 0x5B, 0x38, 0x42, 0x94, 0xB5, 0x49, 0xDA,
Packit c4476c
        0xEF, 0x6E, 0x78, 0x37, 0xCD, 0x30, 0x89, 0xC3, 0x45, 0x50,
Packit c4476c
        0x7B, 0x9C, 0x8C, 0xE7, 0x1C, 0x98, 0x70, 0x71, 0x5D, 0x79,
Packit c4476c
        0x5F, 0xEF, 0xE8, 0x94, 0x85, 0x53, 0x3E, 0xEF, 0xA3, 0x2C,
Packit c4476c
        0xCE, 0x1A, 0xAB, 0x7D, 0xD6, 0x5E, 0x14, 0xCD, 0x51, 0x54,
Packit c4476c
        0x89, 0x9D, 0x77, 0xE4, 0xF8, 0x22, 0xF0, 0x35, 0x10, 0x75,
Packit c4476c
        0x05, 0x71, 0x51, 0x4F, 0x8C, 0x4C, 0x5C, 0x0D, 0x2C, 0x2C,
Packit c4476c
        0xBE, 0x6C, 0x34, 0xEE, 0x12, 0x82, 0x87, 0x03, 0x19, 0x06,
Packit c4476c
        0x12, 0xA8, 0xAA, 0xF4, 0x0D, 0x3C, 0x49, 0xCC, 0x70, 0x5A,
Packit c4476c
        0xD8, 0x32, 0xEE, 0x32, 0x50, 0x85, 0x70, 0xE8, 0x18, 0xFD,
Packit c4476c
        0x74, 0x80, 0x53, 0x32, 0x57, 0xEE, 0x50, 0xC9, 0xAE, 0xEB,
Packit c4476c
        0xAE, 0xB6, 0x22, 0x32, 0x16, 0x6B, 0x8C, 0x59, 0xDA, 0xEE,
Packit c4476c
        0x1D, 0x33, 0xDF, 0x4C, 0xA2, 0x3D
Packit c4476c
    };
Packit c4476c
    static unsigned char dsaq_2048[] = {
Packit c4476c
        0xAD, 0x2D, 0x6E, 0x17, 0xB0, 0xF3, 0xEB, 0xC7, 0xB8, 0xEE,
Packit c4476c
        0x95, 0x78, 0xF2, 0x17, 0xF5, 0x33, 0x01, 0x67, 0xBC, 0xDE,
Packit c4476c
        0x93, 0xFF, 0xEE, 0x40, 0xE8, 0x7F, 0xF1, 0x93, 0x6D, 0x4B,
Packit c4476c
        0x87, 0x13
Packit c4476c
    };
Packit c4476c
    static unsigned char dsag_2048[] = {
Packit c4476c
        0x66, 0x6F, 0xDA, 0x63, 0xA5, 0x8E, 0xD2, 0x4C, 0xD5, 0x45,
Packit c4476c
        0x2D, 0x76, 0x5D, 0x5F, 0xCD, 0x4A, 0xB4, 0x1A, 0x42, 0x35,
Packit c4476c
        0x86, 0x3A, 0x6F, 0xA9, 0xFA, 0x27, 0xAB, 0xDE, 0x03, 0x21,
Packit c4476c
        0x36, 0x0A, 0x07, 0x29, 0xC9, 0x2F, 0x6D, 0x49, 0xA8, 0xF7,
Packit c4476c
        0xC6, 0xF4, 0x92, 0xD7, 0x73, 0xC1, 0xD8, 0x76, 0x0E, 0x61,
Packit c4476c
        0xA7, 0x0B, 0x6E, 0x96, 0xB8, 0xC8, 0xCB, 0x38, 0x35, 0x12,
Packit c4476c
        0x20, 0x79, 0xA5, 0x08, 0x28, 0x35, 0x5C, 0xBC, 0x52, 0x16,
Packit c4476c
        0xAF, 0x52, 0xBA, 0x0F, 0xC3, 0xB1, 0x63, 0x12, 0x27, 0x0B,
Packit c4476c
        0x74, 0xA4, 0x47, 0x43, 0xD6, 0x30, 0xB8, 0x9C, 0x2E, 0x40,
Packit c4476c
        0x14, 0xCD, 0x99, 0x7F, 0xE8, 0x8E, 0x37, 0xB0, 0xA9, 0x3F,
Packit c4476c
        0x54, 0xE9, 0x66, 0x22, 0x61, 0x4C, 0xF8, 0x49, 0x03, 0x57,
Packit c4476c
        0x14, 0x32, 0x1D, 0x37, 0x3D, 0xE2, 0x92, 0xF8, 0x8E, 0xA0,
Packit c4476c
        0x6A, 0x66, 0x63, 0xF0, 0xB0, 0x6E, 0x07, 0x2B, 0x3D, 0xBF,
Packit c4476c
        0xD0, 0x84, 0x6A, 0xAA, 0x1F, 0x30, 0x77, 0x65, 0xE5, 0xFC,
Packit c4476c
        0xF5, 0xEC, 0x55, 0xCE, 0x73, 0xDB, 0xBE, 0xA7, 0x8D, 0x3A,
Packit c4476c
        0x9F, 0x7A, 0xED, 0x4F, 0xAF, 0xA2, 0x80, 0x4C, 0x30, 0x9E,
Packit c4476c
        0x28, 0x49, 0x65, 0x40, 0xF0, 0x03, 0x45, 0x56, 0x99, 0xA2,
Packit c4476c
        0x93, 0x1B, 0x9C, 0x46, 0xDE, 0xBD, 0xA8, 0xAB, 0x5F, 0x90,
Packit c4476c
        0x3F, 0xB7, 0x3F, 0xD4, 0x6F, 0x8D, 0x5A, 0x30, 0xE1, 0xD4,
Packit c4476c
        0x63, 0x3A, 0x6A, 0x7C, 0x8F, 0x24, 0xFC, 0xD9, 0x14, 0x28,
Packit c4476c
        0x09, 0xE4, 0x84, 0x4E, 0x17, 0x43, 0x56, 0xB8, 0xD4, 0x4B,
Packit c4476c
        0xA2, 0x29, 0x45, 0xD3, 0x13, 0xF0, 0xC2, 0x76, 0x9B, 0x01,
Packit c4476c
        0xA0, 0x80, 0x6E, 0x93, 0x63, 0x5E, 0x87, 0x24, 0x20, 0x2A,
Packit c4476c
        0xFF, 0xBB, 0x9F, 0xA8, 0x99, 0x6C, 0xA7, 0x9A, 0x00, 0xB9,
Packit c4476c
        0x7D, 0xDA, 0x66, 0xC9, 0xC0, 0x72, 0x72, 0x22, 0x0F, 0x1A,
Packit c4476c
        0xCC, 0x23, 0xD9, 0xB7, 0x5F, 0x1B
Packit c4476c
    };
Packit c4476c
    DSA *dsa = DSA_new();
Packit c4476c
    BIGNUM *p, *q, *g;
Packit c4476c
Packit c4476c
    if (dsa == NULL)
Packit c4476c
        return NULL;
Packit c4476c
    if (!DSA_set0_pqg(dsa, p = BN_bin2bn(dsap_2048, sizeof(dsap_2048), NULL),
Packit c4476c
                           q = BN_bin2bn(dsaq_2048, sizeof(dsaq_2048), NULL),
Packit c4476c
                           g = BN_bin2bn(dsag_2048, sizeof(dsag_2048), NULL))) {
Packit c4476c
        DSA_free(dsa);
Packit c4476c
        BN_free(p);
Packit c4476c
        BN_free(q);
Packit c4476c
        BN_free(g);
Packit c4476c
        return NULL;
Packit c4476c
    }
Packit c4476c
    return dsa;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int genkeys(void)
Packit c4476c
{
Packit c4476c
    if (!TEST_ptr(dsakey = load_dsa_params()))
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    if (!TEST_int_eq(DSA_generate_key(dsakey), 1))
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int sign_and_verify(int len)
Packit c4476c
{
Packit c4476c
    /*
Packit c4476c
     * Per FIPS 186-4, the hash is recommended to be the same length as q.
Packit c4476c
     * If the hash is longer than q, the leftmost N bits are used; if the hash
Packit c4476c
     * is shorter, then we left-pad (see appendix C.2.1).
Packit c4476c
     */
Packit c4476c
    size_t sigLength;
Packit c4476c
    int digestlen = BN_num_bytes(DSA_get0_q(dsakey));
Packit c4476c
    int ok = 0;
Packit c4476c
Packit c4476c
    unsigned char *dataToSign = OPENSSL_malloc(len);
Packit c4476c
    unsigned char *paddedData = OPENSSL_malloc(digestlen);
Packit c4476c
    unsigned char *signature = NULL;
Packit c4476c
    EVP_PKEY_CTX *ctx = NULL;
Packit c4476c
    EVP_PKEY *pkey = NULL;
Packit c4476c
Packit c4476c
    if (!TEST_ptr(dataToSign) ||
Packit c4476c
        !TEST_ptr(paddedData) ||
Packit c4476c
        !TEST_int_eq(RAND_bytes(dataToSign, len), 1))
Packit c4476c
        goto end;
Packit c4476c
Packit c4476c
    memset(paddedData, 0, digestlen);
Packit c4476c
    if (len > digestlen)
Packit c4476c
        memcpy(paddedData, dataToSign, digestlen);
Packit c4476c
    else
Packit c4476c
        memcpy(paddedData + digestlen - len, dataToSign, len);
Packit c4476c
Packit c4476c
    if (!TEST_ptr(pkey = EVP_PKEY_new()))
Packit c4476c
        goto end;
Packit c4476c
    EVP_PKEY_set1_DSA(pkey, dsakey);
Packit c4476c
Packit c4476c
    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
Packit c4476c
        goto end;
Packit c4476c
    if (!TEST_int_eq(EVP_PKEY_sign_init(ctx), 1))
Packit c4476c
        goto end;
Packit c4476c
Packit c4476c
    if (EVP_PKEY_sign(ctx, NULL, &sigLength, dataToSign, len) != 1) {
Packit c4476c
        TEST_error("Failed to get signature length, len=%d", len);
Packit c4476c
        goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (!TEST_ptr(signature = OPENSSL_malloc(sigLength)))
Packit c4476c
        goto end;
Packit c4476c
Packit c4476c
    if (EVP_PKEY_sign(ctx, signature, &sigLength, dataToSign, len) != 1) {
Packit c4476c
        TEST_error("Failed to sign, len=%d", len);
Packit c4476c
        goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    /* Check that the signature is okay via the EVP interface */
Packit c4476c
    if (!TEST_int_eq(EVP_PKEY_verify_init(ctx), 1))
Packit c4476c
        goto end;
Packit c4476c
Packit c4476c
    /* ... using the same data we just signed */
Packit c4476c
    if (EVP_PKEY_verify(ctx, signature, sigLength, dataToSign, len) != 1) {
Packit c4476c
        TEST_error("EVP verify with unpadded length %d failed\n", len);
Packit c4476c
        goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    /* ... padding/truncating the data to the appropriate digest size */
Packit c4476c
    if (EVP_PKEY_verify(ctx, signature, sigLength, paddedData, digestlen) != 1) {
Packit c4476c
        TEST_error("EVP verify with length %d failed\n", len);
Packit c4476c
        goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    /* Verify again using the raw DSA interface */
Packit c4476c
    if (DSA_verify(0, dataToSign, len, signature, sigLength, dsakey) != 1) {
Packit c4476c
        TEST_error("Verification with unpadded data failed, len=%d", len);
Packit c4476c
        goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (DSA_verify(0, paddedData, digestlen, signature, sigLength, dsakey) != 1) {
Packit c4476c
        TEST_error("verify with length %d failed\n", len);
Packit c4476c
        goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    ok = 1;
Packit c4476c
end:
Packit c4476c
    EVP_PKEY_CTX_free(ctx);
Packit c4476c
    EVP_PKEY_free(pkey);
Packit c4476c
Packit c4476c
    OPENSSL_free(signature);
Packit c4476c
    OPENSSL_free(paddedData);
Packit c4476c
    OPENSSL_free(dataToSign);
Packit c4476c
Packit c4476c
    return ok;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int dsa_exact_size_test(void) {
Packit c4476c
    /*
Packit c4476c
     * For a 2048-bit p, q should be either 224 or 256 bits per the table in
Packit c4476c
     * FIPS 186-4 4.2.
Packit c4476c
     */
Packit c4476c
Packit c4476c
    return sign_and_verify(224 / 8) && sign_and_verify(256 / 8);
Packit c4476c
}
Packit c4476c
Packit c4476c
static int dsa_small_digest_test(void) {
Packit c4476c
    return sign_and_verify(16) && sign_and_verify(1);
Packit c4476c
}
Packit c4476c
Packit c4476c
static int dsa_large_digest_test(void) {
Packit c4476c
    return sign_and_verify(33) && sign_and_verify(64);
Packit c4476c
}
Packit c4476c
Packit c4476c
void cleanup_tests(void)
Packit c4476c
{
Packit c4476c
    DSA_free(dsakey);
Packit c4476c
}
Packit c4476c
Packit c4476c
#endif /* OPENSSL_NO_DSA */
Packit c4476c
Packit c4476c
int setup_tests(void)
Packit c4476c
{
Packit c4476c
#ifndef OPENSSL_NO_DSA
Packit c4476c
    if (!genkeys())
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    ADD_TEST(dsa_exact_size_test);
Packit c4476c
    ADD_TEST(dsa_small_digest_test);
Packit c4476c
    ADD_TEST(dsa_large_digest_test);
Packit c4476c
#endif
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c