summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-01-21 15:05:56 +0100
committerRichard Levitte <levitte@openssl.org>2020-01-28 08:08:22 +0100
commit505b41fc5a7a3cb255d2f62cf4902a1a5c1db2dd (patch)
tree5af49f556aaba41c16ad5f8ad5ddf32c0a5d76a4
parentd5aef5946bd9b113623ad778114768585a1f7a02 (diff)
PROV: Adapt the DSA signature implementation to provide Algorithmidentifiers
Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/10920)
-rw-r--r--crypto/dsa/build.info2
-rw-r--r--crypto/dsa/dsa_aid.c65
-rw-r--r--include/crypto/dsa.h2
-rw-r--r--include/internal/sizes.h1
-rw-r--r--include/openssl/core_names.h11
-rw-r--r--providers/implementations/signature/dsa.c95
6 files changed, 165 insertions, 11 deletions
diff --git a/crypto/dsa/build.info b/crypto/dsa/build.info
index 309fda323e..2cbea9b961 100644
--- a/crypto/dsa/build.info
+++ b/crypto/dsa/build.info
@@ -1,6 +1,6 @@
LIBS=../../libcrypto
-$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c
+$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_aid.c
SOURCE[../../libcrypto]=$COMMON\
dsa_gen.c dsa_key.c dsa_asn1.c \
diff --git a/crypto/dsa/dsa_aid.c b/crypto/dsa/dsa_aid.c
new file mode 100644
index 0000000000..759e5c90e1
--- /dev/null
+++ b/crypto/dsa/dsa_aid.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2020 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
+ */
+
+#include <stdlib.h>
+
+#include <openssl/objects.h>
+#include "crypto/dsa.h"
+
+#define ASN1_SEQUENCE 0x30
+#define ASN1_OID 0x06
+
+/* dsaWithSHA OIDs are of the form: (1 3 14 3 2 |n|) */
+#define ENCODE_ALGORITHMIDENTIFIER_SHA(name, n) \
+ static const unsigned char algorithmidentifier_##name##_der[] = { \
+ ASN1_SEQUENCE, 0x07, \
+ ASN1_OID, 0x05, 1 * 40 + 3, 14, 3, 2, n \
+}
+
+ENCODE_ALGORITHMIDENTIFIER_SHA(sha, 13);
+ENCODE_ALGORITHMIDENTIFIER_SHA(sha1, 27);
+
+/* dsaWithSHA OIDs are of the form: (2 16 840 1 101 3 4 3 |n|) */
+#define ENCODE_ALGORITHMIDENTIFIER_SHAx(name, n) \
+ static const unsigned char algorithmidentifier_##name##_der[] = { \
+ ASN1_SEQUENCE, 0x0b, \
+ ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 3, n \
+}
+
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha224, 1);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha256, 2);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha384, 3);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha512, 4);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_224, 5);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_256, 6);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_384, 7);
+ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_512, 8);
+
+#define MD_CASE(name) \
+ case NID_##name: \
+ *len = sizeof(algorithmidentifier_##name##_der); \
+ return algorithmidentifier_##name##_der
+
+const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len)
+{
+ switch (md_nid) {
+ MD_CASE(sha);
+ MD_CASE(sha1);
+ MD_CASE(sha224);
+ MD_CASE(sha256);
+ MD_CASE(sha384);
+ MD_CASE(sha512);
+ MD_CASE(sha3_224);
+ MD_CASE(sha3_256);
+ MD_CASE(sha3_384);
+ MD_CASE(sha3_512);
+ default:
+ return NULL;
+ }
+}
diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h
index 9afae37d2a..041ebd4f7f 100644
--- a/include/crypto/dsa.h
+++ b/include/crypto/dsa.h
@@ -11,3 +11,5 @@
int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst,
int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa);
+
+const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len);
diff --git a/include/internal/sizes.h b/include/internal/sizes.h
index fab5cbdec7..00a5d3e88e 100644
--- a/include/internal/sizes.h
+++ b/include/internal/sizes.h
@@ -16,5 +16,6 @@
*/
# define OSSL_MAX_NAME_SIZE 50 /* Algorithm name */
# define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */
+# define OSSL_MAX_ALGORITHM_ID_SIZE 256 /* AlgorithmIdentifier DER */
#endif
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 20b06ff96b..cd701ab937 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -87,7 +87,16 @@ extern "C" {
#define OSSL_DIGEST_PARAM_FLAGS "flags" /* ulong */
/* Known DIGEST names (not a complete list) */
-#define OSSL_DIGEST_NAME_MD5 "MD5"
+#define OSSL_DIGEST_NAME_MD5 "MD5"
+#define OSSL_DIGEST_NAME_SHA1 "SHA1"
+#define OSSL_DIGEST_NAME_SHA2_224 "SHA2-224"
+#define OSSL_DIGEST_NAME_SHA2_256 "SHA2-256"
+#define OSSL_DIGEST_NAME_SHA2_384 "SHA2-384"
+#define OSSL_DIGEST_NAME_SHA2_512 "SHA2-512"
+#define OSSL_DIGEST_NAME_SHA3_224 "SHA3-224"
+#define OSSL_DIGEST_NAME_SHA3_256 "SHA3-256"
+#define OSSL_DIGEST_NAME_SHA3_384 "SHA3-384"
+#define OSSL_DIGEST_NAME_SHA3_512 "SHA3-512"
#define OSSL_DIGEST_NAME_KECCAK_KMAC128 "KECCAK-KMAC-128"
#define OSSL_DIGEST_NAME_KECCAK_KMAC256 "KECCAK-KMAC-256"
diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c
index 9892e6d5e4..e8d9cd0b81 100644
--- a/providers/implementations/signature/dsa.c
+++ b/providers/implementations/signature/dsa.c
@@ -7,13 +7,18 @@
* https://www.openssl.org/source/license.html
*/
+#include <string.h>
+
#include <openssl/crypto.h>
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
+#include <openssl/err.h>
#include <openssl/dsa.h>
#include <openssl/params.h>
#include <openssl/evp.h>
+#include "internal/nelem.h"
#include "internal/sizes.h"
+#include "prov/providercommonerr.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "crypto/dsa.h"
@@ -51,6 +56,12 @@ typedef struct {
DSA *dsa;
size_t mdsize;
char mdname[OSSL_MAX_NAME_SIZE];
+
+ /* The Algorithm Identifier of the combined signature agorithm */
+ unsigned char aid[OSSL_MAX_ALGORITHM_ID_SIZE];
+ size_t aid_len;
+
+ /* main digest */
EVP_MD *md;
EVP_MD_CTX *mdctx;
} PROV_DSA_CTX;
@@ -116,28 +127,88 @@ static int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen,
return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa);
}
+static int get_md_nid(const EVP_MD *md)
+{
+ /*
+ * Because the DSA library deals with NIDs, we need to translate.
+ * We do so using EVP_MD_is_a(), and therefore need a name to NID
+ * map.
+ */
+ static const OSSL_ITEM name_to_nid[] = {
+ { NID_sha1, OSSL_DIGEST_NAME_SHA1 },
+ { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 },
+ { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 },
+ { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 },
+ { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 },
+ { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 },
+ { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 },
+ { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 },
+ { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 },
+ };
+ size_t i;
+ int mdnid = NID_undef;
+
+ if (md == NULL)
+ goto end;
+
+ for (i = 0; i < OSSL_NELEM(name_to_nid); i++) {
+ if (EVP_MD_is_a(md, name_to_nid[i].ptr)) {
+ mdnid = (int)name_to_nid[i].id;
+ break;
+ }
+ }
+
+ if (mdnid == NID_undef)
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
+
+ end:
+ return mdnid;
+}
+
static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname,
const char *props, void *vdsa)
{
PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- EVP_MD *md;
+ size_t algorithmidentifier_len = 0;
+ const unsigned char *algorithmidentifier;
+
+ EVP_MD_CTX_free(pdsactx->mdctx);
+ EVP_MD_free(pdsactx->md);
+ pdsactx->mdctx = NULL;
+ pdsactx->mdsize = 0;
+ pdsactx->md = NULL;
if (!dsa_signature_init(vpdsactx, vdsa))
return 0;
- md = EVP_MD_fetch(pdsactx->libctx, mdname, props);
- if (md == NULL)
- return 0;
- pdsactx->md = md;
- pdsactx->mdsize = EVP_MD_size(md);
+ pdsactx->md = EVP_MD_fetch(pdsactx->libctx, mdname, props);
+ algorithmidentifier =
+ dsa_algorithmidentifier_encoding(get_md_nid(pdsactx->md),
+ &algorithmidentifier_len);
+
+ if (algorithmidentifier == NULL)
+ goto error;
+
+ pdsactx->mdsize = EVP_MD_size(pdsactx->md);
pdsactx->mdctx = EVP_MD_CTX_new();
if (pdsactx->mdctx == NULL)
- return 0;
+ goto error;
- if (!EVP_DigestInit_ex(pdsactx->mdctx, md, NULL))
- return 0;
+ memcpy(pdsactx->aid, algorithmidentifier, algorithmidentifier_len);
+ pdsactx->aid_len = algorithmidentifier_len;
+
+ if (!EVP_DigestInit_ex(pdsactx->mdctx, pdsactx->md, NULL))
+ goto error;
return 1;
+
+ error:
+ EVP_MD_CTX_free(pdsactx->mdctx);
+ EVP_MD_free(pdsactx->md);
+ pdsactx->mdctx = NULL;
+ pdsactx->mdsize = 0;
+ pdsactx->md = NULL;
+ return 0;
}
int dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data,
@@ -254,6 +325,11 @@ static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params)
if (pdsactx == NULL || params == NULL)
return 0;
+ p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
+ if (p != NULL
+ && !OSSL_PARAM_set_octet_string(p, pdsactx->aid, pdsactx->aid_len))
+ return 0;
+
p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
if (p != NULL && !OSSL_PARAM_set_size_t(p, pdsactx->mdsize))
return 0;
@@ -268,6 +344,7 @@ static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params)
}
static const OSSL_PARAM known_gettable_ctx_params[] = {
+ OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_END