]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
nettle/gost: provide GOST keywrapping support
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Thu, 14 Jun 2018 12:39:19 +0000 (15:39 +0300)
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Thu, 7 Nov 2019 15:41:28 +0000 (18:41 +0300)
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
lib/nettle/Makefile.am
lib/nettle/gost/gost-wrap.c [new file with mode: 0644]
lib/nettle/gost/gost28147.h

index 035102f127445012fe5569562540d54efe5a5a47..b194c82f8920d36971bc3fe9b4a2cb14a58edb70 100644 (file)
@@ -74,7 +74,7 @@ endif
 if ENABLE_GOST
 libcrypto_la_SOURCES += \
        gost/nettle-write.h \
-       gost/gost28147.c gost/gost28147.h \
+       gost/gost28147.c gost/gost28147.h gost/gost-wrap.c \
        gost/gosthash94.c gost/gosthash94.h gost/gosthash94-meta.c \
        gost/streebog.c gost/streebog.h gost/streebog-meta.c \
        gost/hmac-gosthash94.c gost/hmac-streebog.c gost/hmac-gost.h
diff --git a/lib/nettle/gost/gost-wrap.c b/lib/nettle/gost/gost-wrap.c
new file mode 100644 (file)
index 0000000..63e1c32
--- /dev/null
@@ -0,0 +1,132 @@
+/* GOST 28147-89 (Magma) implementation
+ *
+ * Copyright: 2015, 2016 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ * Copyright: 2009-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnutls_int.h>
+
+#include <string.h>
+
+#include <nettle/macros.h>
+#include "gost28147.h"
+#include <nettle/cfb.h>
+#include <nettle/memops.h>
+
+void
+gost28147_kdf_cryptopro(const struct gost28147_param *param,
+                      const uint8_t *in,
+                      const uint8_t *ukm,
+                      uint8_t *out)
+{
+       struct gost28147_ctx ctx;
+       int i;
+
+       memcpy(out, in, GOST28147_KEY_SIZE);
+       for (i = 0; i < 8; i++) {
+               uint8_t mask;
+               uint8_t *p;
+               uint8_t iv[GOST28147_BLOCK_SIZE];
+               uint32_t block[2] = {0, 0};
+               uint32_t t;
+
+               for (p = out, mask = 1; mask; mask <<= 1) {
+                       t = LE_READ_UINT32(p);
+                       p += 4;
+                       if (mask & ukm[i])
+                               block[0] += t;
+                       else
+                               block[1] += t;
+               }
+
+               LE_WRITE_UINT32(iv + 0, block[0]);
+               LE_WRITE_UINT32(iv + 4, block[1]);
+
+               gost28147_set_key(&ctx, out);
+               gost28147_set_param(&ctx, param);
+               cfb_encrypt(&ctx,
+                           (nettle_cipher_func*)gost28147_encrypt_for_cfb,
+                           GOST28147_BLOCK_SIZE, iv,
+                           GOST28147_KEY_SIZE, out, out);
+       }
+}
+
+void
+gost28147_key_wrap_cryptopro(const struct gost28147_param *param,
+                            const uint8_t *kek,
+                            const uint8_t *ukm, size_t ukm_size,
+                            const uint8_t *cek,
+                            uint8_t *enc,
+                            uint8_t *imit)
+{
+       uint8_t kd[GOST28147_KEY_SIZE];
+       struct gost28147_ctx ctx;
+       struct gost28147_imit_ctx ictx;
+
+       assert(ukm_size >= GOST28147_IMIT_BLOCK_SIZE);
+
+       gost28147_kdf_cryptopro(param, kek, ukm, kd);
+       gost28147_set_key(&ctx, kd);
+       gost28147_set_param(&ctx, param);
+       gost28147_encrypt(&ctx, GOST28147_KEY_SIZE, enc, cek);
+
+       gost28147_imit_init(&ictx);
+       gost28147_imit_set_key(&ictx, GOST28147_KEY_SIZE, kd);
+       gost28147_imit_set_param(&ictx, param);
+       gost28147_imit_set_nonce(&ictx, ukm);
+       gost28147_imit_update(&ictx, GOST28147_KEY_SIZE, cek);
+       gost28147_imit_digest(&ictx, GOST28147_IMIT_DIGEST_SIZE, imit);
+}
+
+int
+gost28147_key_unwrap_cryptopro(const struct gost28147_param *param,
+                              const uint8_t *kek,
+                              const uint8_t *ukm, size_t ukm_size,
+                              const uint8_t *enc,
+                              const uint8_t *imit,
+                              uint8_t *cek)
+{
+       uint8_t kd[GOST28147_KEY_SIZE];
+       uint8_t mac[GOST28147_IMIT_DIGEST_SIZE];
+       struct gost28147_ctx ctx;
+       struct gost28147_imit_ctx ictx;
+
+       assert(ukm_size >= GOST28147_IMIT_BLOCK_SIZE);
+
+       gost28147_kdf_cryptopro(param, kek, ukm, kd);
+       gost28147_set_key(&ctx, kd);
+       gost28147_set_param(&ctx, param);
+       gost28147_decrypt(&ctx, GOST28147_KEY_SIZE, cek, enc);
+
+       gost28147_imit_init(&ictx);
+       gost28147_imit_set_key(&ictx, GOST28147_KEY_SIZE, kd);
+       gost28147_imit_set_param(&ictx, param);
+       gost28147_imit_set_nonce(&ictx, ukm);
+       gost28147_imit_update(&ictx, GOST28147_KEY_SIZE, cek);
+       gost28147_imit_digest(&ictx, GOST28147_IMIT_DIGEST_SIZE, mac);
+
+       return memeql_sec(mac, imit, GOST28147_IMIT_DIGEST_SIZE);
+}
index 5fbab90ef17eb3030013008ae29cffa72d1ca23f..ae4a385589d05171631fb241792dea1ef9f8a141 100644 (file)
@@ -69,6 +69,10 @@ extern "C" {
 #define gost28147_cnt_set_iv _gnutls_gost28147_cnt_set_iv
 #define gost28147_cnt_crypt _gnutls_gost28147_cnt_crypt
 
+#define gost28147_kdf_cryptopro _gnutls_gost28147_kdf_cryptopro
+#define gost28147_key_wrap_cryptopro _gnutls_gost28147_key_wrap_cryptopro
+#define gost28147_key_unwrap_cryptopro _gnutls_gost28147_key_unwrap_cryptopro
+
 #define gost28147_imit_init _gnutls_gost28147_imit_init
 #define gost28147_imit_set_key _gnutls_gost28147_imit_set_key
 #define gost28147_imit_set_nonce _gnutls_gost28147_imit_set_nonce
@@ -147,6 +151,27 @@ gost28147_cnt_crypt(struct gost28147_cnt_ctx *ctx,
                    size_t length, uint8_t *dst,
                    const uint8_t *src);
 
+void
+gost28147_kdf_cryptopro(const struct gost28147_param *param,
+                      const uint8_t *in,
+                      const uint8_t *ukm,
+                      uint8_t *out);
+void
+gost28147_key_wrap_cryptopro(const struct gost28147_param *param,
+                            const uint8_t *kek,
+                            const uint8_t *ukm, size_t ukm_size,
+                            const uint8_t *cek,
+                            uint8_t *enc,
+                            uint8_t *imit);
+
+int
+gost28147_key_unwrap_cryptopro(const struct gost28147_param *param,
+                              const uint8_t *kek,
+                              const uint8_t *ukm, size_t ukm_size,
+                              const uint8_t *enc,
+                              const uint8_t *imit,
+                              uint8_t *cek);
+
 #define GOST28147_IMIT_DIGEST_SIZE 4
 #define GOST28147_IMIT_BLOCK_SIZE GOST28147_BLOCK_SIZE
 #define GOST28147_IMIT_KEY_SIZE GOST28147_KEY_SIZE