summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortobhe <tobhe@openbsd.org>2020-12-06 19:46:42 +0000
committertobhe <tobhe@openbsd.org>2020-12-06 19:46:42 +0000
commit753a20ac1fbfa7e24fe97f56a80a26becc03f643 (patch)
tree39fc09805605c4d26c5e1a60a8e00df9aedcf4f3
parentmbg(4): more tsleep(9) -> tsleep_nsec(9) (diff)
downloadwireguard-openbsd-753a20ac1fbfa7e24fe97f56a80a26becc03f643.tar.xz
wireguard-openbsd-753a20ac1fbfa7e24fe97f56a80a26becc03f643.zip
Add support for RSASSA-PSS signature verification (RFC 7427).
ok patrick@
-rw-r--r--sbin/iked/crypto.c122
1 files changed, 110 insertions, 12 deletions
diff --git a/sbin/iked/crypto.c b/sbin/iked/crypto.c
index d0c5a915698..7736c77bf55 100644
--- a/sbin/iked/crypto.c
+++ b/sbin/iked/crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crypto.c,v 1.30 2020/12/03 21:57:36 tobhe Exp $ */
+/* $OpenBSD: crypto.c,v 1.31 2020/12/06 19:46:42 tobhe Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -65,22 +65,109 @@ static const uint8_t ecdsa_sha512[] = {
0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
0x3d, 0x04, 0x03, 0x04
};
+/* RFC 7427, A.4.3 RSASSA-PSS with SHA-256 */
+static const uint8_t rsapss_sha256[] = {
+ 0x30, 0x46, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x39, 0xa0,
+ 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
+ 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30,
+ 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03,
+ 0x02, 0x01, 0x20, 0xa3, 0x03, 0x02, 0x01, 0x01
+};
+/* RSASSA-PSS SHA-384 */
+static const uint8_t rsapss_sha384[] = {
+ 0x30, 0x46, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0,
+ 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
+ 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30,
+ 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03,
+ 0x02, 0x01, 0x30, 0xa3, 0x03, 0x02, 0x01, 0x01
+};
+/* RSASSA-PSS SHA-512 */
+static const uint8_t rsapss_sha512[] = {
+ 0x30, 0x46, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0,
+ 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00,
+ 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30,
+ 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03,
+ 0x02, 0x01, 0x40, 0xa3, 0x03, 0x02, 0x01, 0x01
+};
+/* RSASSA-PSS SHA-256, no trailer */
+static const uint8_t rsapss_sha256nt[] = {
+ 0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0,
+ 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
+ 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30,
+ 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03,
+ 0x02, 0x01, 0x20
+};
+/* RSASSA-PSS SHA-384, no trailer */
+static const uint8_t rsapss_sha384nt[] = {
+ 0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0,
+ 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
+ 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30,
+ 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03,
+ 0x02, 0x01, 0x30
+};
+/* RSASSA-PSS SHA-512, no trailer */
+static const uint8_t rsapss_sha512nt[] = {
+ 0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0,
+ 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00,
+ 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30,
+ 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03,
+ 0x02, 0x01, 0x40
+};
+
+#define FLAG_RSA_PSS 0x00001
static const struct {
int sc_keytype;
const EVP_MD *(*sc_md)(void);
uint8_t sc_len;
const uint8_t *sc_oid;
+ uint32_t sc_flags;
} schemes[] = {
- { EVP_PKEY_RSA, EVP_sha256, sizeof(sha256WithRSA), sha256WithRSA },
- { EVP_PKEY_RSA, EVP_sha384, sizeof(sha384WithRSA), sha384WithRSA },
- { EVP_PKEY_RSA, EVP_sha512, sizeof(sha512WithRSA), sha512WithRSA },
- { EVP_PKEY_EC, EVP_sha256, sizeof(ecdsa_sha256), ecdsa_sha256 },
- { EVP_PKEY_EC, EVP_sha384, sizeof(ecdsa_sha384), ecdsa_sha384 },
- { EVP_PKEY_EC, EVP_sha512, sizeof(ecdsa_sha512), ecdsa_sha512 },
+ { EVP_PKEY_RSA, EVP_sha256, sizeof(sha256WithRSA), sha256WithRSA, 0 },
+ { EVP_PKEY_RSA, EVP_sha384, sizeof(sha384WithRSA), sha384WithRSA, 0 },
+ { EVP_PKEY_RSA, EVP_sha512, sizeof(sha512WithRSA), sha512WithRSA, 0 },
+ { EVP_PKEY_EC, EVP_sha256, sizeof(ecdsa_sha256), ecdsa_sha256, 0 },
+ { EVP_PKEY_EC, EVP_sha384, sizeof(ecdsa_sha384), ecdsa_sha384, 0 },
+ { EVP_PKEY_EC, EVP_sha512, sizeof(ecdsa_sha512), ecdsa_sha512, 0 },
+ { EVP_PKEY_RSA, EVP_sha256, sizeof(rsapss_sha256), rsapss_sha256,
+ FLAG_RSA_PSS },
+ { EVP_PKEY_RSA, EVP_sha384, sizeof(rsapss_sha384), rsapss_sha384,
+ FLAG_RSA_PSS },
+ { EVP_PKEY_RSA, EVP_sha512, sizeof(rsapss_sha512), rsapss_sha512,
+ FLAG_RSA_PSS },
+ { EVP_PKEY_RSA, EVP_sha256, sizeof(rsapss_sha256nt), rsapss_sha256nt,
+ FLAG_RSA_PSS },
+ { EVP_PKEY_RSA, EVP_sha384, sizeof(rsapss_sha384nt), rsapss_sha384nt,
+ FLAG_RSA_PSS },
+ { EVP_PKEY_RSA, EVP_sha512, sizeof(rsapss_sha512nt), rsapss_sha512nt,
+ FLAG_RSA_PSS },
};
-int _dsa_verify_init(struct iked_dsa *, const uint8_t *, size_t);
+int _dsa_verify_init(struct iked_dsa *, const uint8_t *, size_t, int *);
int _dsa_verify_prepare(struct iked_dsa *, uint8_t **, size_t *,
uint8_t **);
int _dsa_sign_encode(struct iked_dsa *, uint8_t *, size_t, size_t *);
@@ -793,12 +880,14 @@ dsa_setkey(struct iked_dsa *dsa, void *key, size_t keylen, uint8_t type)
}
int
-_dsa_verify_init(struct iked_dsa *dsa, const uint8_t *sig, size_t len)
+_dsa_verify_init(struct iked_dsa *dsa, const uint8_t *sig, size_t len,
+ int *flags)
{
uint8_t oidlen;
size_t i;
int keytype;
+ *flags = 0;
if (dsa->dsa_priv != NULL)
return (0);
/*
@@ -837,6 +926,7 @@ _dsa_verify_init(struct iked_dsa *dsa, const uint8_t *sig, size_t len)
memcmp(sig + 1, schemes[i].sc_oid,
schemes[i].sc_len) == 0) {
dsa->dsa_priv = (*schemes[i].sc_md)();
+ *flags = schemes[i].sc_flags;
log_debug("%s: signature scheme %zd selected",
__func__, i);
return (0);
@@ -849,7 +939,8 @@ _dsa_verify_init(struct iked_dsa *dsa, const uint8_t *sig, size_t len)
int
dsa_init(struct iked_dsa *dsa, const void *buf, size_t len)
{
- int ret;
+ int ret, flags = 0;
+ EVP_PKEY_CTX *pctx = NULL;
if (dsa->dsa_hmac) {
if (!HMAC_Init_ex(dsa->dsa_ctx, ibuf_data(dsa->dsa_keydata),
@@ -862,10 +953,17 @@ dsa_init(struct iked_dsa *dsa, const void *buf, size_t len)
ret = EVP_DigestSignInit(dsa->dsa_ctx, NULL, dsa->dsa_priv,
NULL, dsa->dsa_key);
else {
- if ((ret = _dsa_verify_init(dsa, buf, len)) != 0)
+ /* set dsa_priv */
+ if ((ret = _dsa_verify_init(dsa, buf, len, &flags)) != 0)
return (ret);
- ret = EVP_DigestVerifyInit(dsa->dsa_ctx, NULL, dsa->dsa_priv,
+ ret = EVP_DigestVerifyInit(dsa->dsa_ctx, &pctx, dsa->dsa_priv,
NULL, dsa->dsa_key);
+ if (ret == 1 && flags == FLAG_RSA_PSS) {
+ if (EVP_PKEY_CTX_set_rsa_padding(pctx,
+ RSA_PKCS1_PSS_PADDING) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0)
+ return (-1);
+ }
}
return (ret == 1 ? 0 : -1);