mirror of
https://abf.rosa.ru/djam/libressl.git
synced 2025-02-23 08:02:54 +00:00
275 lines
8.7 KiB
Diff
275 lines
8.7 KiB
Diff
From 363239bfbe92bfe654c21f1b181531ebdd8fa8ad Mon Sep 17 00:00:00 2001
|
|
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
|
|
Date: Sat, 18 Apr 2020 18:34:28 +0300
|
|
Subject: [PATCH 86/87] kdftree: add support for TLSTREE rekeying algorithm
|
|
|
|
GOST CTR-OMAC ciphersuites use external rekeying names TLSTREE. Add
|
|
support for this transformation.
|
|
|
|
Sponsored by ROSA Linux
|
|
|
|
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
|
|
---
|
|
src/lib/libcrypto/kdftree/kdftree.c | 3 +-
|
|
src/lib/libcrypto/kdftree/kdftree.h | 23 ++++
|
|
src/lib/libcrypto/kdftree/kdftree_locl.h | 31 +++++
|
|
src/lib/libcrypto/kdftree/tlstree.c | 154 +++++++++++++++++++++++
|
|
4 files changed, 210 insertions(+), 1 deletion(-)
|
|
create mode 100644 src/lib/libcrypto/kdftree/kdftree_locl.h
|
|
create mode 100644 src/lib/libcrypto/kdftree/tlstree.c
|
|
|
|
diff --git a/src/lib/libcrypto/kdftree/kdftree.c b/src/lib/libcrypto/kdftree/kdftree.c
|
|
index 4dc7b0096..957ca2875 100644
|
|
--- a/src/lib/libcrypto/kdftree/kdftree.c
|
|
+++ b/src/lib/libcrypto/kdftree/kdftree.c
|
|
@@ -18,6 +18,7 @@
|
|
|
|
#include <openssl/kdftree.h>
|
|
#include <openssl/hmac.h>
|
|
+#include "kdftree_locl.h"
|
|
|
|
#include <string.h>
|
|
|
|
@@ -26,7 +27,7 @@
|
|
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
|
*((c)++)=(unsigned char)(((l) )&0xff))
|
|
|
|
-static int
|
|
+int
|
|
kdf_tree_block(HMAC_CTX *ctx,
|
|
const unsigned char *i, unsigned int i_length,
|
|
const unsigned char *label, unsigned int label_length,
|
|
diff --git a/src/lib/libcrypto/kdftree/kdftree.h b/src/lib/libcrypto/kdftree/kdftree.h
|
|
index 132f70690..378b06b51 100644
|
|
--- a/src/lib/libcrypto/kdftree/kdftree.h
|
|
+++ b/src/lib/libcrypto/kdftree/kdftree.h
|
|
@@ -40,6 +40,29 @@ int KDF_TREE_SIMPLE(const EVP_MD *md, ENGINE *impl,
|
|
const unsigned char *seed, unsigned int seed_length,
|
|
unsigned char *out);
|
|
|
|
+/* TLSTREE is an external re-keying function (see
|
|
+ * draft-smyshlyaev-tls12-gost-suites Section 8 for the definition, RFC 8645
|
|
+ * Section 5.2.2 for the discussion of the approach. */
|
|
+
|
|
+/* Opaque */
|
|
+typedef struct TLSTREE_CTX_st TLSTREE_CTX;
|
|
+
|
|
+typedef struct tlstree_const_st {
|
|
+ uint64_t c1, c2, c3;
|
|
+} TLSTREE_CONST;
|
|
+
|
|
+TLSTREE_CTX *TLSTREE_CTX_new(void);
|
|
+void TLSTREE_CTX_free(TLSTREE_CTX *ctx);
|
|
+
|
|
+int TLSTREE_Init(TLSTREE_CTX *ctx,
|
|
+ const TLSTREE_CONST *tlsconst,
|
|
+ const EVP_MD *md, ENGINE *impl,
|
|
+ const unsigned char *key,
|
|
+ int key_length);
|
|
+int TLSTREE_GET(TLSTREE_CTX *ctx,
|
|
+ unsigned char *seq,
|
|
+ unsigned char *out);
|
|
+
|
|
#if defined(__cplusplus)
|
|
} /* extern C */
|
|
#endif
|
|
diff --git a/src/lib/libcrypto/kdftree/kdftree_locl.h b/src/lib/libcrypto/kdftree/kdftree_locl.h
|
|
new file mode 100644
|
|
index 000000000..0eff3156d
|
|
--- /dev/null
|
|
+++ b/src/lib/libcrypto/kdftree/kdftree_locl.h
|
|
@@ -0,0 +1,31 @@
|
|
+/* $OpenBSD: kdftree_locl.h,v 1.4 2019/11/21 20:02:20 tim Exp $ */
|
|
+/* Copyright (c) 2020, Dmitry Baryshkov
|
|
+ *
|
|
+ * Sponsored by ROSA Linux
|
|
+ *
|
|
+ * Permission to use, copy, modify, and/or distribute this software for any
|
|
+ * purpose with or without fee is hereby granted, provided that the above
|
|
+ * copyright notice and this permission notice appear in all copies.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
+ */
|
|
+
|
|
+#ifndef OPENSSL_HEADER_KDFTREE_LOCL_H
|
|
+#define OPENSSL_HEADER_KDFTREE_LOCL_H
|
|
+
|
|
+#include <openssl/hmac.h>
|
|
+
|
|
+int kdf_tree_block(HMAC_CTX *ctx,
|
|
+ const unsigned char *i, unsigned int i_length,
|
|
+ const unsigned char *label, unsigned int label_length,
|
|
+ const unsigned char *seed, unsigned int seed_length,
|
|
+ const unsigned char *l, unsigned int l_length,
|
|
+ unsigned char *out, unsigned int *length);
|
|
+
|
|
+#endif /* OPENSSL_HEADER_KDFTREE_LOCL_H */
|
|
diff --git a/src/lib/libcrypto/kdftree/tlstree.c b/src/lib/libcrypto/kdftree/tlstree.c
|
|
new file mode 100644
|
|
index 000000000..5c3322675
|
|
--- /dev/null
|
|
+++ b/src/lib/libcrypto/kdftree/tlstree.c
|
|
@@ -0,0 +1,154 @@
|
|
+/* $OpenBSD: tlstree.h,v 1.4 2019/11/21 20:02:20 tim Exp $ */
|
|
+/* Copyright (c) 2020, Dmitry Baryshkov
|
|
+ *
|
|
+ * Sponsored by ROSA Linux
|
|
+ *
|
|
+ * Permission to use, copy, modify, and/or distribute this software for any
|
|
+ * purpose with or without fee is hereby granted, provided that the above
|
|
+ * copyright notice and this permission notice appear in all copies.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
+ */
|
|
+
|
|
+#include <openssl/kdftree.h>
|
|
+#include "kdftree_locl.h"
|
|
+#include <string.h>
|
|
+
|
|
+#define ll2c(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>>48)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>>40)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l) )&0xff))
|
|
+
|
|
+#define c2ll(c,l) (l =((uint64_t)(*((c)++))) , \
|
|
+ l|=((uint64_t)(*((c)++)))<< 8, \
|
|
+ l|=((uint64_t)(*((c)++)))<<16, \
|
|
+ l|=((uint64_t)(*((c)++)))<<24, \
|
|
+ l|=((uint64_t)(*((c)++)))<<32, \
|
|
+ l|=((uint64_t)(*((c)++)))<<40, \
|
|
+ l|=((uint64_t)(*((c)++)))<<48, \
|
|
+ l|=((uint64_t)(*((c)++)))<<56)
|
|
+
|
|
+#define TLSTREE_L1 ((const unsigned char *)"level1")
|
|
+#define TLSTREE_L2 ((const unsigned char *)"level2")
|
|
+#define TLSTREE_L3 ((const unsigned char *)"level3")
|
|
+#define TLSTREE_L_LENGTH 6
|
|
+
|
|
+#define TLSTREE_KEY_LENGTH 32
|
|
+
|
|
+struct TLSTREE_CTX_st {
|
|
+ uint64_t seq;
|
|
+ const TLSTREE_CONST *tlsconst;
|
|
+ HMAC_CTX ctx1, ctx2, ctx3;
|
|
+ unsigned char current[TLSTREE_KEY_LENGTH];
|
|
+};
|
|
+
|
|
+TLSTREE_CTX *
|
|
+TLSTREE_CTX_new(void)
|
|
+{
|
|
+ TLSTREE_CTX *ctx;
|
|
+
|
|
+ ctx = malloc(sizeof(TLSTREE_CTX));
|
|
+ if (!ctx)
|
|
+ return NULL;
|
|
+
|
|
+ HMAC_CTX_init(&ctx->ctx1);
|
|
+ HMAC_CTX_init(&ctx->ctx2);
|
|
+ HMAC_CTX_init(&ctx->ctx3);
|
|
+ ctx->tlsconst = NULL;
|
|
+
|
|
+ return ctx;
|
|
+}
|
|
+
|
|
+void
|
|
+TLSTREE_CTX_free(TLSTREE_CTX *ctx)
|
|
+{
|
|
+ if (ctx == NULL)
|
|
+ return;
|
|
+
|
|
+ HMAC_CTX_cleanup(&ctx->ctx1);
|
|
+ HMAC_CTX_cleanup(&ctx->ctx2);
|
|
+ HMAC_CTX_cleanup(&ctx->ctx3);
|
|
+}
|
|
+
|
|
+static int tlstree_one(HMAC_CTX *ctx, const unsigned char *label, uint64_t seq, unsigned char *out)
|
|
+{
|
|
+ unsigned char seed[8], *p = seed;
|
|
+ static const unsigned char data1[1] = { 0x01 };
|
|
+ static const unsigned char data2[2] = { 0x01, 0x00 };
|
|
+ int dummy = TLSTREE_KEY_LENGTH;
|
|
+
|
|
+ ll2c(seq, p);
|
|
+ return kdf_tree_block(ctx, data1, 1, label, TLSTREE_L_LENGTH, seed, 8, data2, 2, out, &dummy);
|
|
+}
|
|
+
|
|
+int
|
|
+TLSTREE_Init(TLSTREE_CTX *ctx,
|
|
+ const TLSTREE_CONST *tlsconst,
|
|
+ const EVP_MD *md, ENGINE *impl,
|
|
+ const unsigned char *key,
|
|
+ int key_length)
|
|
+{
|
|
+ unsigned char tmp[TLSTREE_KEY_LENGTH];
|
|
+
|
|
+ /* Support only reasonable cases, which allow simplification of KDF_TREE calls */
|
|
+ if (key_length != EVP_MD_size(md) ||
|
|
+ key_length != TLSTREE_KEY_LENGTH)
|
|
+ return 0;
|
|
+
|
|
+ if (!ctx || !tlsconst || !md || !key)
|
|
+ return 0;
|
|
+
|
|
+ ctx->tlsconst = tlsconst;
|
|
+ ctx->seq = 0;
|
|
+
|
|
+ if (!HMAC_Init_ex(&ctx->ctx1, key, TLSTREE_KEY_LENGTH, md, impl) ||
|
|
+ !tlstree_one(&ctx->ctx1, TLSTREE_L1, 0, tmp) ||
|
|
+ !HMAC_Init_ex(&ctx->ctx2, tmp, TLSTREE_KEY_LENGTH, md, impl) ||
|
|
+ !tlstree_one(&ctx->ctx2, TLSTREE_L2, 0, tmp) ||
|
|
+ !HMAC_Init_ex(&ctx->ctx3, tmp, TLSTREE_KEY_LENGTH, md, impl) ||
|
|
+ !tlstree_one(&ctx->ctx3, TLSTREE_L3, 0, ctx->current))
|
|
+ return 0;
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+int
|
|
+TLSTREE_GET(TLSTREE_CTX *ctx,
|
|
+ unsigned char *seq,
|
|
+ unsigned char *out)
|
|
+{
|
|
+ uint64_t s;
|
|
+ unsigned char *p = seq;
|
|
+ unsigned char tmp[TLSTREE_KEY_LENGTH];
|
|
+
|
|
+ c2ll(p, s);
|
|
+
|
|
+ if ((s & ctx->tlsconst->c1) != (ctx->seq & ctx->tlsconst->c1)) {
|
|
+ if (!tlstree_one(&ctx->ctx1, TLSTREE_L1, 0, tmp) ||
|
|
+ !HMAC_Init_ex(&ctx->ctx2, tmp, TLSTREE_KEY_LENGTH, NULL, NULL))
|
|
+ return 0;
|
|
+ }
|
|
+ if ((s & ctx->tlsconst->c2) != (ctx->seq & ctx->tlsconst->c2)) {
|
|
+ if (!tlstree_one(&ctx->ctx2, TLSTREE_L2, 0, tmp) ||
|
|
+ !HMAC_Init_ex(&ctx->ctx3, tmp, TLSTREE_KEY_LENGTH, NULL, NULL))
|
|
+ return 0;
|
|
+ }
|
|
+ if ((s & ctx->tlsconst->c3) != (ctx->seq & ctx->tlsconst->c3)) {
|
|
+ if (!tlstree_one(&ctx->ctx3, TLSTREE_L3, 0, ctx->current))
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ memcpy(out, ctx->current, TLSTREE_KEY_LENGTH);
|
|
+
|
|
+ return 1;
|
|
+}
|
|
--
|
|
2.17.1
|
|
|