mirror of
https://github.com/openssl/openssl.git
synced 2026-05-07 20:12:39 +00:00
c721580653
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org> MergeDate: Tue Mar 10 14:37:54 2026 Release: yes
168 lines
4.2 KiB
C
168 lines
4.2 KiB
C
/*
|
|
* Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
/*
|
|
* DSA low level APIs are deprecated for public use, but still ok for
|
|
* internal use.
|
|
*/
|
|
#include "internal/deprecated.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "testutil.h"
|
|
|
|
#include <openssl/evp.h>
|
|
#include <openssl/err.h>
|
|
#include <openssl/rand.h>
|
|
|
|
#ifndef OPENSSL_NO_DSA
|
|
#include <openssl/dsa.h>
|
|
#include "helpers/predefined_dsaparams.h"
|
|
|
|
static DSA *dsakey;
|
|
|
|
static int genkeys(void)
|
|
{
|
|
if (!TEST_ptr(dsakey = load_dsa_params()))
|
|
return 0;
|
|
|
|
if (!TEST_int_eq(DSA_generate_key(dsakey), 1))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int sign_and_verify(int len)
|
|
{
|
|
/*
|
|
* Per FIPS 186-4, the hash is recommended to be the same length as q.
|
|
* If the hash is longer than q, the leftmost N bits are used; if the hash
|
|
* is shorter, then we left-pad (see appendix C.2.1).
|
|
*/
|
|
size_t sigLength;
|
|
int digestlen = BN_num_bytes(DSA_get0_q(dsakey));
|
|
int ok = 0;
|
|
|
|
unsigned char *dataToSign = OPENSSL_malloc(len);
|
|
unsigned char *paddedData = OPENSSL_malloc(digestlen);
|
|
unsigned char *signature = NULL;
|
|
EVP_PKEY_CTX *ctx = NULL;
|
|
EVP_PKEY *pkey = NULL;
|
|
|
|
if (!TEST_ptr(dataToSign) || !TEST_ptr(paddedData) || !TEST_int_eq(RAND_bytes(dataToSign, len), 1))
|
|
goto end;
|
|
|
|
memset(paddedData, 0, digestlen);
|
|
if (len > digestlen)
|
|
memcpy(paddedData, dataToSign, digestlen);
|
|
else
|
|
memcpy(paddedData + digestlen - len, dataToSign, len);
|
|
|
|
if (!TEST_ptr(pkey = EVP_PKEY_new()))
|
|
goto end;
|
|
EVP_PKEY_set1_DSA(pkey, dsakey);
|
|
|
|
if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
|
|
goto end;
|
|
if (!TEST_int_eq(EVP_PKEY_sign_init(ctx), 1))
|
|
goto end;
|
|
|
|
if (EVP_PKEY_sign(ctx, NULL, &sigLength, dataToSign, len) != 1) {
|
|
TEST_error("Failed to get signature length, len=%d", len);
|
|
goto end;
|
|
}
|
|
|
|
if (!TEST_ptr(signature = OPENSSL_malloc(sigLength)))
|
|
goto end;
|
|
|
|
if (EVP_PKEY_sign(ctx, signature, &sigLength, dataToSign, len) != 1) {
|
|
TEST_error("Failed to sign, len=%d", len);
|
|
goto end;
|
|
}
|
|
|
|
/* Check that the signature is okay via the EVP interface */
|
|
if (!TEST_int_eq(EVP_PKEY_verify_init(ctx), 1))
|
|
goto end;
|
|
|
|
/* ... using the same data we just signed */
|
|
if (EVP_PKEY_verify(ctx, signature, sigLength, dataToSign, len) != 1) {
|
|
TEST_error("EVP verify with unpadded length %d failed\n", len);
|
|
goto end;
|
|
}
|
|
|
|
/* ... padding/truncating the data to the appropriate digest size */
|
|
if (EVP_PKEY_verify(ctx, signature, sigLength, paddedData, digestlen) != 1) {
|
|
TEST_error("EVP verify with length %d failed\n", len);
|
|
goto end;
|
|
}
|
|
|
|
/* Verify again using the raw DSA interface */
|
|
if (DSA_verify(0, dataToSign, len, signature, (int)sigLength, dsakey) != 1) {
|
|
TEST_error("Verification with unpadded data failed, len=%d", len);
|
|
goto end;
|
|
}
|
|
|
|
if (DSA_verify(0, paddedData, digestlen, signature, (int)sigLength, dsakey) != 1) {
|
|
TEST_error("verify with length %d failed\n", len);
|
|
goto end;
|
|
}
|
|
|
|
ok = 1;
|
|
end:
|
|
EVP_PKEY_CTX_free(ctx);
|
|
EVP_PKEY_free(pkey);
|
|
|
|
OPENSSL_free(signature);
|
|
OPENSSL_free(paddedData);
|
|
OPENSSL_free(dataToSign);
|
|
|
|
return ok;
|
|
}
|
|
|
|
static int dsa_exact_size_test(void)
|
|
{
|
|
/*
|
|
* For a 2048-bit p, q should be either 224 or 256 bits per the table in
|
|
* FIPS 186-4 4.2.
|
|
*/
|
|
|
|
return sign_and_verify(224 / 8) && sign_and_verify(256 / 8);
|
|
}
|
|
|
|
static int dsa_small_digest_test(void)
|
|
{
|
|
return sign_and_verify(16) && sign_and_verify(1);
|
|
}
|
|
|
|
static int dsa_large_digest_test(void)
|
|
{
|
|
return sign_and_verify(33) && sign_and_verify(64);
|
|
}
|
|
|
|
void cleanup_tests(void)
|
|
{
|
|
DSA_free(dsakey);
|
|
}
|
|
|
|
#endif /* OPENSSL_NO_DSA */
|
|
|
|
int setup_tests(void)
|
|
{
|
|
#ifndef OPENSSL_NO_DSA
|
|
if (!genkeys())
|
|
return 0;
|
|
|
|
ADD_TEST(dsa_exact_size_test);
|
|
ADD_TEST(dsa_small_digest_test);
|
|
ADD_TEST(dsa_large_digest_test);
|
|
#endif
|
|
return 1;
|
|
}
|