]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
lib: add Magma/Kuznyechik ciphers support
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Fri, 21 Sep 2018 19:11:14 +0000 (22:11 +0300)
committerDmitry Baryshkov <dbaryshkov@gmail.com>
Sat, 6 Jun 2020 21:59:22 +0000 (00:59 +0300)
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
devel/libgnutls-latest-x86_64.abi
lib/algorithms/ciphers.c
lib/includes/gnutls/gnutls.h.in
lib/nettle/cipher.c

index 07618659af272605f34f00f909c61b3fa6f30c5f..c3f736f3b93f69c110e93947d440cb794ac293bf 100644 (file)
       <enumerator name='GNUTLS_CIPHER_AES_128_SIV' value='37'/>
       <enumerator name='GNUTLS_CIPHER_AES_256_SIV' value='38'/>
       <enumerator name='GNUTLS_CIPHER_AES_192_GCM' value='39'/>
+      <enumerator name='GNUTLS_CIPHER_MAGMA_CTR_ACPKM' value='40'/>
+      <enumerator name='GNUTLS_CIPHER_KUZNYECHIK_CTR_ACPKM' value='41'/>
       <enumerator name='GNUTLS_CIPHER_IDEA_PGP_CFB' value='200'/>
       <enumerator name='GNUTLS_CIPHER_3DES_PGP_CFB' value='201'/>
       <enumerator name='GNUTLS_CIPHER_CAST5_PGP_CFB' value='202'/>
index d57c1d5dba0f89813c7ae22da281596c337ee0e2..0ffa1f651fe45aa83de4b608c397c9ecc0791c1a 100644 (file)
@@ -304,6 +304,20 @@ static const cipher_entry_st algorithms[] = {
          .type = CIPHER_STREAM,
          .implicit_iv = 8,
          .cipher_iv = 8},
+       { .name = "MAGMA-CTR-ACPKM",
+         .id = GNUTLS_CIPHER_MAGMA_CTR_ACPKM,
+         .blocksize = 8,
+         .keysize = 32,
+         .type = CIPHER_STREAM,
+         .implicit_iv = 4,
+         .cipher_iv = 8},
+       { .name = "KUZNYECHIK-CTR-ACPKM",
+         .id = GNUTLS_CIPHER_KUZNYECHIK_CTR_ACPKM,
+         .blocksize = 16,
+         .keysize = 32,
+         .type = CIPHER_STREAM,
+         .implicit_iv = 8,
+         .cipher_iv = 16},
        { .name = "3DES-CBC",
          .id = GNUTLS_CIPHER_3DES_CBC,
          .blocksize = 8,
index 264da238a099d96801a59beea836bf7893885b0e..fb7f37a4ccb1f40138e435b0587c666365574e04 100644 (file)
@@ -128,6 +128,8 @@ extern "C" {
  *                             cipher-stealing requires to know where the message actually terminates
  *                             in order to be able to compute where the stealing occurs.
  * @GNUTLS_CIPHER_GOST28147_TC26Z_CNT: GOST 28147-89 (Magma) cipher in CNT mode with TC26 Z S-box.
+ * @GNUTLS_CIPHER_MAGMA_CTR_ACPKM: GOST R 34.12-2015 (Magma) cipher in CTR-ACPKM mode.
+ * @GNUTLS_CIPHER_KUZNYECHIK_CTR_ACPKM: GOST R 34.12-2015 (Kuznyechik) cipher in CTR-ACPKM mode.
  * @GNUTLS_CIPHER_IDEA_PGP_CFB: IDEA in CFB mode (placeholder - unsupported).
  * @GNUTLS_CIPHER_3DES_PGP_CFB: 3DES in CFB mode (placeholder - unsupported).
  * @GNUTLS_CIPHER_CAST5_PGP_CFB: CAST5 in CFB mode (placeholder - unsupported).
@@ -188,6 +190,8 @@ typedef enum gnutls_cipher_algorithm {
        GNUTLS_CIPHER_AES_128_SIV = 37,
        GNUTLS_CIPHER_AES_256_SIV = 38,
        GNUTLS_CIPHER_AES_192_GCM = 39,
+       GNUTLS_CIPHER_MAGMA_CTR_ACPKM = 40,
+       GNUTLS_CIPHER_KUZNYECHIK_CTR_ACPKM = 41,
 
        /* used only for PGP internals. Ignored in TLS/SSL
         */
index 69ed70213d971a725c49ee191cd29d46a6f46f8d..b0a52deb5345fe402eecd96c6c405f7533367bcd 100644 (file)
 #else
 #include <nettle/gost28147.h>
 #endif
+#ifndef HAVE_NETTLE_MAGMA_SET_KEY
+#include "gost/magma.h"
+#else
+#include <nettle/magma.h>
+#endif
+#ifndef HAVE_NETTLE_KUZNYECHIK_SET_KEY
+#include "gost/kuznyechik.h"
+#else
+#include <nettle/kuznyechik.h>
+#endif
+#include "gost/acpkm.h"
+#include <nettle/ctr.h>
 #endif
 #include <nettle/nettle-meta.h>
 #include <nettle/cbc.h>
@@ -160,6 +172,18 @@ _cbc_decrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
 }
 
 #if ENABLE_GOST
+struct magma_acpkm_ctx {
+       uint8_t iv[MAGMA_BLOCK_SIZE];
+       struct acpkm_ctx ctx;
+       struct magma_ctx cipher;
+};
+
+struct kuznyechik_acpkm_ctx {
+       uint8_t iv[KUZNYECHIK_BLOCK_SIZE];
+       struct acpkm_ctx ctx;
+       struct kuznyechik_ctx cipher;
+};
+
 static void
 _cfb_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
                const uint8_t * src)
@@ -178,6 +202,16 @@ _cfb_decrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
                    length, dst, src);
 }
 
+static void
+_ctr_acpkm_crypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
+          const uint8_t * src)
+{
+       /* Use context-specific IV which comes as a first field */
+       ctr_crypt(ctx->ctx_ptr, ctx->cipher->encrypt_block,
+                 ctx->cipher->block_size, ctx->ctx_ptr,
+                 length, dst, src);
+}
+
 static void
 _gost28147_set_key_tc26z(void *ctx, const uint8_t *key)
 {
@@ -231,6 +265,58 @@ _gost28147_cnt_crypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst
 {
        gost28147_cnt_crypt((void *)ctx->ctx_ptr, length, dst, src);
 }
+
+static void
+_magma_acpkm_crypt(struct magma_acpkm_ctx *ctx,
+                 size_t length, uint8_t *dst,
+                 const uint8_t *src)
+{
+  acpkm_crypt(&ctx->ctx, &ctx->cipher,
+             (nettle_cipher_func *)magma_encrypt,
+             (nettle_set_key_func *)magma_set_key,
+             length, dst, src);
+}
+
+static void
+_kuznyechik_acpkm_crypt(struct kuznyechik_acpkm_ctx *ctx,
+                      size_t length, uint8_t *dst,
+                      const uint8_t *src)
+{
+  acpkm_crypt(&ctx->ctx, &ctx->cipher,
+             (nettle_cipher_func *)kuznyechik_encrypt,
+             (nettle_set_key_func *)kuznyechik_set_key,
+             length, dst, src);
+}
+
+static void
+_magma_ctr_acpkm_set_key(struct magma_acpkm_ctx *ctx, const uint8_t *key)
+{
+       magma_set_key(&ctx->cipher, key);
+       ctx->ctx.pos = 0;
+       ctx->ctx.N = 1024;
+}
+
+static void
+_magma_ctr_acpkm_set_iv(struct magma_acpkm_ctx *ctx, size_t length, const uint8_t *iv)
+{
+       memcpy(ctx->iv, iv, length);
+       memset(ctx->iv + length, 0, MAGMA_BLOCK_SIZE - length);
+}
+
+static void
+_kuznyechik_ctr_acpkm_set_key(struct kuznyechik_acpkm_ctx *ctx, const uint8_t *key)
+{
+       kuznyechik_set_key(&ctx->cipher, key);
+       ctx->ctx.pos = 0;
+       ctx->ctx.N = 4096;
+}
+
+static void
+_kuznyechik_ctr_acpkm_set_iv(struct kuznyechik_acpkm_ctx *ctx, size_t length, const uint8_t *iv)
+{
+       memcpy(ctx->iv, iv, length);
+       memset(ctx->iv + length, 0, KUZNYECHIK_BLOCK_SIZE - length);
+}
 #endif
 
 static void
@@ -881,6 +967,34 @@ static const struct nettle_cipher_st builtin_ciphers[] = {
           .set_decrypt_key = _gost28147_cnt_set_key_tc26z,
           .set_iv = (setiv_func)_gost28147_cnt_set_nonce,
        },
+       {
+          .algo = GNUTLS_CIPHER_MAGMA_CTR_ACPKM,
+          .block_size = MAGMA_BLOCK_SIZE,
+          .key_size = MAGMA_KEY_SIZE,
+          .encrypt_block = (nettle_cipher_func*)_magma_acpkm_crypt,
+          .decrypt_block = (nettle_cipher_func*)_magma_acpkm_crypt,
+
+          .ctx_size = sizeof(struct magma_acpkm_ctx),
+          .encrypt = _ctr_acpkm_crypt,
+          .decrypt = _ctr_acpkm_crypt,
+          .set_encrypt_key = (nettle_set_key_func*)_magma_ctr_acpkm_set_key,
+          .set_decrypt_key = (nettle_set_key_func*)_magma_ctr_acpkm_set_key,
+          .set_iv = (setiv_func)_magma_ctr_acpkm_set_iv,
+       },
+       {
+          .algo = GNUTLS_CIPHER_KUZNYECHIK_CTR_ACPKM,
+          .block_size = KUZNYECHIK_BLOCK_SIZE,
+          .key_size = KUZNYECHIK_KEY_SIZE,
+          .encrypt_block = (nettle_cipher_func*)_kuznyechik_acpkm_crypt,
+          .decrypt_block = (nettle_cipher_func*)_kuznyechik_acpkm_crypt,
+
+          .ctx_size = sizeof(struct kuznyechik_acpkm_ctx),
+          .encrypt = _ctr_acpkm_crypt,
+          .decrypt = _ctr_acpkm_crypt,
+          .set_encrypt_key = (nettle_set_key_func*)_kuznyechik_ctr_acpkm_set_key,
+          .set_decrypt_key = (nettle_set_key_func*)_kuznyechik_ctr_acpkm_set_key,
+          .set_iv = (setiv_func)_kuznyechik_ctr_acpkm_set_iv,
+       },
 #endif
        {  .algo = GNUTLS_CIPHER_AES_128_CFB8,
           .block_size = AES_BLOCK_SIZE,