mirror of
https://abf.rosa.ru/djam/libressl.git
synced 2025-02-23 16:12:53 +00:00
250 lines
7.4 KiB
Diff
250 lines
7.4 KiB
Diff
![]() |
From 608d04f4bc23c308b6792b414b8782669379ff09 Mon Sep 17 00:00:00 2001
|
||
|
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
|
||
|
Date: Sat, 18 Apr 2020 14:17:34 +0300
|
||
|
Subject: [PATCH 41/87] kdftree: add functions implementing KDF_TREE function
|
||
|
|
||
|
Add support for KDF_TREE function from RFC 7836. Unline original RFC
|
||
|
which enforces using of GOST R 34.11 (Streebog-256), these functions are
|
||
|
made generic to use any EVP_MD underneath.
|
||
|
|
||
|
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
|
||
|
---
|
||
|
src/lib/libcrypto/Symbols.list | 2 +
|
||
|
src/lib/libcrypto/kdftree/kdftree.c | 156 ++++++++++++++++++++++++++++
|
||
|
src/lib/libcrypto/kdftree/kdftree.h | 47 +++++++++
|
||
|
3 files changed, 205 insertions(+)
|
||
|
create mode 100644 src/lib/libcrypto/kdftree/kdftree.c
|
||
|
create mode 100644 src/lib/libcrypto/kdftree/kdftree.h
|
||
|
|
||
|
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
|
||
|
index c4edd9eb6..287c86d2c 100644
|
||
|
--- a/src/lib/libcrypto/Symbols.list
|
||
|
+++ b/src/lib/libcrypto/Symbols.list
|
||
|
@@ -1838,6 +1838,8 @@ HMAC_Update
|
||
|
ISSUING_DIST_POINT_free
|
||
|
ISSUING_DIST_POINT_it
|
||
|
ISSUING_DIST_POINT_new
|
||
|
+KDF_TREE
|
||
|
+KDF_TREE_SIMPLE
|
||
|
LONG_it
|
||
|
MD4
|
||
|
MD4_Final
|
||
|
diff --git a/src/lib/libcrypto/kdftree/kdftree.c b/src/lib/libcrypto/kdftree/kdftree.c
|
||
|
new file mode 100644
|
||
|
index 000000000..4dc7b0096
|
||
|
--- /dev/null
|
||
|
+++ b/src/lib/libcrypto/kdftree/kdftree.c
|
||
|
@@ -0,0 +1,156 @@
|
||
|
+/* $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 <openssl/hmac.h>
|
||
|
+
|
||
|
+#include <string.h>
|
||
|
+
|
||
|
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
||
|
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||
|
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||
|
+ *((c)++)=(unsigned char)(((l) )&0xff))
|
||
|
+
|
||
|
+static 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)
|
||
|
+{
|
||
|
+ /* i label 0x00 seed l */
|
||
|
+ static const unsigned char data[1] = { 0x00 };
|
||
|
+
|
||
|
+ if (!HMAC_Init_ex(ctx, NULL, 0, NULL, NULL) ||
|
||
|
+ !HMAC_Update(ctx, i, i_length) ||
|
||
|
+ !HMAC_Update(ctx, label, label_length) ||
|
||
|
+ !HMAC_Update(ctx, data, 1) ||
|
||
|
+ !HMAC_Update(ctx, seed, seed_length) ||
|
||
|
+ !HMAC_Update(ctx, l, l_length))
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ return HMAC_Final(ctx, out, length);
|
||
|
+}
|
||
|
+
|
||
|
+int KDF_TREE(const EVP_MD *md, ENGINE *impl,
|
||
|
+ const unsigned char *key, unsigned int key_length,
|
||
|
+ const unsigned char *label, unsigned int label_length,
|
||
|
+ const unsigned char *seed, unsigned int seed_length,
|
||
|
+ size_t r,
|
||
|
+ unsigned char *out, unsigned int length)
|
||
|
+{
|
||
|
+ HMAC_CTX ctx;
|
||
|
+ unsigned int i;
|
||
|
+ unsigned char i_block[4], l_block[8];
|
||
|
+ unsigned int l_length, l_off;
|
||
|
+ unsigned char *p;
|
||
|
+ int md_size = EVP_MD_size(md);
|
||
|
+
|
||
|
+ HMAC_CTX_init(&ctx);
|
||
|
+
|
||
|
+ if (!HMAC_Init_ex(&ctx, key, key_length, md, impl))
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ p = l_block;
|
||
|
+ /* bitlength */
|
||
|
+ l2c(length >> 29, p);
|
||
|
+ l2c(length * 8, p);
|
||
|
+
|
||
|
+ /* Calculate how many bytes will it take */
|
||
|
+ for (l_off = 0; l_off < 8; l_off++)
|
||
|
+ if (l_block[l_off] != 0)
|
||
|
+ break;
|
||
|
+
|
||
|
+ l_length = 8 - l_off;
|
||
|
+ for (i = 1; length >= md_size; i++) {
|
||
|
+ unsigned int block = md_size;
|
||
|
+ p = i_block;
|
||
|
+ l2c(i, p);
|
||
|
+ if (!kdf_tree_block(&ctx,
|
||
|
+ i_block + 4 - r, r,
|
||
|
+ label, label_length,
|
||
|
+ seed, seed_length,
|
||
|
+ l_block + l_off, l_length,
|
||
|
+ out, &block)) {
|
||
|
+ HMAC_CTX_cleanup(&ctx);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ out += block;
|
||
|
+ length -= block;
|
||
|
+ }
|
||
|
+ if (length > 0) {
|
||
|
+ unsigned char tmp[EVP_MAX_MD_SIZE];
|
||
|
+ unsigned int block = length;
|
||
|
+
|
||
|
+ p = i_block;
|
||
|
+ l2c(i, p);
|
||
|
+ if (!kdf_tree_block(&ctx,
|
||
|
+ i_block + 4 - r, r,
|
||
|
+ label, label_length,
|
||
|
+ seed, seed_length,
|
||
|
+ l_block + l_off, l_length,
|
||
|
+ tmp, &block)) {
|
||
|
+ HMAC_CTX_cleanup(&ctx);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ memcpy(out, tmp, length);
|
||
|
+ }
|
||
|
+ HMAC_CTX_cleanup(&ctx);
|
||
|
+
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+int KDF_TREE_SIMPLE(const EVP_MD *md, ENGINE *impl,
|
||
|
+ const unsigned char *key, unsigned int key_length,
|
||
|
+ const unsigned char *label, unsigned int label_length,
|
||
|
+ const unsigned char *seed, unsigned int seed_length,
|
||
|
+ unsigned char *out)
|
||
|
+{
|
||
|
+ HMAC_CTX ctx;
|
||
|
+ static unsigned char data1[1] = { 0x01 };
|
||
|
+ unsigned char data2[2];
|
||
|
+ int d2_length;
|
||
|
+ int md_size = EVP_MD_size(md);
|
||
|
+ int ret = 1;
|
||
|
+
|
||
|
+ /* bitlength */
|
||
|
+ if (md_size >= 32) {
|
||
|
+ data2[0] = md_size / 32;
|
||
|
+ data2[1] = (md_size * 8) & 0xff;
|
||
|
+ d2_length = 2;
|
||
|
+ } else {
|
||
|
+ data2[0] = (md_size * 8) & 0xff;
|
||
|
+ d2_length = 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ HMAC_CTX_init(&ctx);
|
||
|
+
|
||
|
+ if (!HMAC_Init_ex(&ctx, key, key_length, md, impl) ||
|
||
|
+ !kdf_tree_block(&ctx,
|
||
|
+ data1, 1,
|
||
|
+ label, label_length,
|
||
|
+ seed, seed_length,
|
||
|
+ data2, d2_length,
|
||
|
+ out, &md_size))
|
||
|
+ ret = 0;
|
||
|
+
|
||
|
+ HMAC_CTX_cleanup(&ctx);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
diff --git a/src/lib/libcrypto/kdftree/kdftree.h b/src/lib/libcrypto/kdftree/kdftree.h
|
||
|
new file mode 100644
|
||
|
index 000000000..132f70690
|
||
|
--- /dev/null
|
||
|
+++ b/src/lib/libcrypto/kdftree/kdftree.h
|
||
|
@@ -0,0 +1,47 @@
|
||
|
+/* $OpenBSD: kdftree.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_H
|
||
|
+#define OPENSSL_HEADER_KDFTREE_H
|
||
|
+
|
||
|
+#if defined(__cplusplus)
|
||
|
+extern "C" {
|
||
|
+#endif
|
||
|
+
|
||
|
+#include <openssl/evp.h>
|
||
|
+
|
||
|
+/* See RFC 7836 Sections 4.4 */
|
||
|
+int KDF_TREE(const EVP_MD *md, ENGINE *impl,
|
||
|
+ const unsigned char *key, unsigned int key_length,
|
||
|
+ const unsigned char *label, unsigned int label_length,
|
||
|
+ const unsigned char *seed, unsigned int seed_length,
|
||
|
+ size_t r,
|
||
|
+ unsigned char *out, unsigned int length);
|
||
|
+
|
||
|
+/* KDF function from RFC 7836 Section 4.5. Fast equivalent of KDF_TREE with r=1 and L=EVP_MD_size(md) */
|
||
|
+int KDF_TREE_SIMPLE(const EVP_MD *md, ENGINE *impl,
|
||
|
+ const unsigned char *key, unsigned int key_length,
|
||
|
+ const unsigned char *label, unsigned int label_length,
|
||
|
+ const unsigned char *seed, unsigned int seed_length,
|
||
|
+ unsigned char *out);
|
||
|
+
|
||
|
+#if defined(__cplusplus)
|
||
|
+} /* extern C */
|
||
|
+#endif
|
||
|
+
|
||
|
+#endif /* OPENSSL_HEADER_KDFTREE_H */
|
||
|
--
|
||
|
2.17.1
|
||
|
|