libressl/0059-gost-support-specifying-old-or-new-KEG-derivation-fo.patch

145 lines
4.2 KiB
Diff
Raw Normal View History

From cd0eec15fae54c7ca1b11109f85503b3cfb02217 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 8 Apr 2020 21:27:04 +0300
Subject: [PATCH 59/87] gost: support specifying old or new (KEG) derivation
format
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/gost/gost.h | 4 ++
src/lib/libcrypto/gost/gostr341001_pmeth.c | 68 +++++++++++++++++++++-
2 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index 6a2b60670..694906b76 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -229,6 +229,7 @@ size_t GOST_KEY_get_size(const GOST_KEY * r);
#define EVP_PKEY_CTRL_GOST_SET_DIGEST (EVP_PKEY_ALG_CTRL+3)
#define EVP_PKEY_CTRL_GOST_GET_DIGEST (EVP_PKEY_ALG_CTRL+4)
#define EVP_PKEY_CTRL_GOST_ENC_FORMAT (EVP_PKEY_ALG_CTRL+5)
+#define EVP_PKEY_CTRL_GOST_DERIVE_FORMAT (EVP_PKEY_ALG_CTRL+6)
#define GOST_SIG_FORMAT_SR_BE 0
#define GOST_SIG_FORMAT_RS_LE 1
@@ -237,6 +238,9 @@ size_t GOST_KEY_get_size(const GOST_KEY * r);
#define GOST_ENC_FORMAT_PSKEY_MAGMA 1 /* CMS, TLS CTR-OMAC, Magma-encoded */
#define GOST_ENC_FORMAT_PSKEY_KUZNYECHIK 2 /* CMS, TLS CTR-OMAC, Kuznyechik-encoded */
+#define GOST_DERIVE_FORMAT_4490 0 /* RFC 4490, TLS CNT-IMIT */
+#define GOST_DERIVE_FORMAT_KEG 1 /* CMS, TLS CTR-OMAC */
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c
index 07ca4d3a3..e21101ddc 100644
--- a/src/lib/libcrypto/gost/gostr341001_pmeth.c
+++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c
@@ -137,6 +137,7 @@ struct gost_pmeth_data {
int peer_key_used;
int sig_format;
int enc_format;
+ int derive_format;
};
static int
@@ -468,8 +469,8 @@ err:
return ret;
}
-int
-pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+static int
+pkey_gost01_derive_4490(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
/*
* Public key of peer in the ctx field peerkey
@@ -504,6 +505,38 @@ pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
return 1;
}
+static int
+pkey_gost01_derive_keg(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+{
+ /*
+ * Public key of peer in the ctx field peerkey
+ * Our private key in the ctx pkey
+ * ukm is in the algorithm specific context data
+ */
+ EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
+ EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
+ struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+
+ if (data->shared_ukm == NULL) {
+ GOSTerror(GOST_R_UKM_NOT_SET);
+ return 0;
+ }
+
+ if (key == NULL) {
+ *keylen = 64;
+ return 64;
+ }
+
+ if (!gost_keg(peer_key, my_key, data->digest_nid, data->shared_ukm, key)) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ return 0;
+ }
+
+ *keylen = 64;
+
+ return 1;
+}
+
int
pkey_gost01_encrypt_4490(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len,
const unsigned char *key, size_t key_len)
@@ -816,6 +849,21 @@ pkey_gost01_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *out_len,
}
}
+int
+pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+{
+ struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx);
+
+ switch (pctx->derive_format) {
+ case GOST_DERIVE_FORMAT_4490:
+ return pkey_gost01_derive_4490(ctx, key, keylen);
+ case GOST_DERIVE_FORMAT_KEG:
+ return pkey_gost01_derive_keg(ctx, key, keylen);
+ default:
+ return -1;
+ }
+}
+
static int
pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
@@ -911,6 +959,22 @@ pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
pctx->enc_format = p1;
return 1;
break;
+ case EVP_PKEY_CTRL_GOST_DERIVE_FORMAT:
+ switch (p1) {
+ case GOST_DERIVE_FORMAT_4490:
+ /* All keys are supported */
+ break;
+ case GOST_DERIVE_FORMAT_KEG:
+ if (pctx->digest_nid != NID_id_tc26_gost3411_2012_256 &&
+ pctx->digest_nid != NID_id_tc26_gost3411_2012_512)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ pctx->derive_format = p1;
+ return 1;
+ break;
default:
return -2;
}
--
2.17.1