]> www.wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
Magma/Kuznyechik ASN1 parameters and functions
authorDmitry Belyavskiy <beldmit@gmail.com>
Sun, 3 May 2020 16:42:05 +0000 (19:42 +0300)
committerDmitry Belyavskiy <beldmit@gmail.com>
Mon, 4 May 2020 12:50:12 +0000 (15:50 +0300)
CMakeLists.txt
e_gost_err.c
e_gost_err.h
gost.txt
gost_asn1.c
gost_gost2015.c [new file with mode: 0644]
gost_gost2015.h [new file with mode: 0644]
gost_lcl.h

index ada88421409f0b7653436304a7102705adba37f0..e38b49607211c3b5c26d731ba6b2317f8769efc2 100644 (file)
@@ -160,6 +160,7 @@ set(GOST_ENGINE_SOURCE_FILES
         gost_pmeth.c
         gost_omac.c
         gost_omac_acpkm.c
+        gost_gost2015.c
         )
 
 add_executable(test_digest test_digest.c)
index b7aa855203572c3b187435e6ef6f824f3f0219b4..43f328dfbba87204c4b90eda4d9e59e682e2987c 100644 (file)
@@ -20,6 +20,10 @@ static ERR_STRING_DATA GOST_str_functs[] = {
      "encode_gost_algor_params"},
     {ERR_PACK(0, GOST_F_FILL_GOST_EC_PARAMS, 0), "fill_GOST_EC_params"},
     {ERR_PACK(0, GOST_F_GET_ENCRYPTION_PARAMS, 0), "get_encryption_params"},
+    {ERR_PACK(0, GOST_F_GOST2015_GET_ASN1_PARAMS, 0),
+     "gost2015_get_asn1_params"},
+    {ERR_PACK(0, GOST_F_GOST2015_SET_ASN1_PARAMS, 0),
+     "gost2015_set_asn1_params"},
     {ERR_PACK(0, GOST_F_GOST89_GET_ASN1_PARAMETERS, 0),
      "gost89_get_asn1_parameters"},
     {ERR_PACK(0, GOST_F_GOST89_SET_ASN1_PARAMETERS, 0),
index f656239833414ecb12968a08b7e15dbd367a0b42..d17a165aaae487e1fa26bc5240443ad8e6bed848 100644 (file)
@@ -33,6 +33,8 @@ void ERR_GOST_error(int function, int reason, char *file, int line);
 # define GOST_F_ENCODE_GOST_ALGOR_PARAMS                  101
 # define GOST_F_FILL_GOST_EC_PARAMS                       102
 # define GOST_F_GET_ENCRYPTION_PARAMS                     103
+# define GOST_F_GOST2015_GET_ASN1_PARAMS                  158
+# define GOST_F_GOST2015_SET_ASN1_PARAMS                  159
 # define GOST_F_GOST89_GET_ASN1_PARAMETERS                104
 # define GOST_F_GOST89_SET_ASN1_PARAMETERS                105
 # define GOST_F_GOST_CIPHER_CTL                           106
index 959b99cc608d748934f70c5c84c2023d7d654d28..538cccfadaa024f21d87e95fb0ecc273404c927e 100644 (file)
--- a/gost.txt
+++ b/gost.txt
@@ -10,6 +10,8 @@ GOST_F_DECODE_GOST_ALGOR_PARAMS:100:decode_gost_algor_params
 GOST_F_ENCODE_GOST_ALGOR_PARAMS:101:encode_gost_algor_params
 GOST_F_FILL_GOST_EC_PARAMS:102:fill_GOST_EC_params
 GOST_F_GET_ENCRYPTION_PARAMS:103:get_encryption_params
+GOST_F_GOST2015_GET_ASN1_PARAMS:158:gost2015_get_asn1_params
+GOST_F_GOST2015_SET_ASN1_PARAMS:159:gost2015_set_asn1_params
 GOST_F_GOST89_GET_ASN1_PARAMETERS:104:gost89_get_asn1_parameters
 GOST_F_GOST89_SET_ASN1_PARAMETERS:105:gost89_set_asn1_parameters
 GOST_F_GOST_CIPHER_CTL:106:gost_cipher_ctl
index 35b90509ea921c2aa1dc876a453c19d5832cb06f..cb8883eb5463d4104f723b8a300559636eaac892 100644 (file)
@@ -48,6 +48,11 @@ ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) =
 } ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS)
 IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
 
+ASN1_NDEF_SEQUENCE(GOST2015_CIPHER_PARAMS) = {
+       ASN1_SIMPLE(GOST2015_CIPHER_PARAMS, ukm, ASN1_OCTET_STRING),
+} ASN1_NDEF_SEQUENCE_END(GOST2015_CIPHER_PARAMS)
+IMPLEMENT_ASN1_FUNCTIONS(GOST2015_CIPHER_PARAMS)
+
 ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) =
 {                               /* FIXME incomplete */
     ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT)
diff --git a/gost_gost2015.c b/gost_gost2015.c
new file mode 100644 (file)
index 0000000..6ae65d6
--- /dev/null
@@ -0,0 +1,122 @@
+#include "gost_lcl.h"
+#include "gost_gost2015.h"
+#include "e_gost_err.h"
+#include <string.h>
+
+int gost2015_final_call(EVP_CIPHER_CTX *ctx, EVP_MD_CTX *omac_ctx, size_t mac_size,
+                       unsigned char *encrypted_mac,
+                       int (*do_cipher) (EVP_CIPHER_CTX *ctx,
+                               unsigned char *out,
+                               const unsigned char *in,
+                               size_t inl))
+{
+       unsigned char calculated_mac[KUZNYECHIK_MAC_MAX_SIZE];
+       memset(calculated_mac, 0, KUZNYECHIK_MAC_MAX_SIZE);
+
+       if (EVP_CIPHER_CTX_encrypting(ctx)) {
+               EVP_DigestSignFinal(omac_ctx, calculated_mac, &mac_size);
+
+               if (do_cipher(ctx, encrypted_mac, calculated_mac, mac_size) <= 0) {
+                         return -1;
+               }
+       } else {
+               unsigned char expected_mac[KUZNYECHIK_MAC_MAX_SIZE];
+
+               memset(expected_mac, 0, KUZNYECHIK_MAC_MAX_SIZE);
+               EVP_DigestSignFinal(omac_ctx, calculated_mac, &mac_size);
+
+               if (do_cipher(ctx, expected_mac, encrypted_mac, mac_size) <= 0) {
+                         return -1;
+               }
+
+               if (CRYPTO_memcmp(expected_mac, calculated_mac, mac_size) != 0)
+                       return -1;
+       }
+       return 0;
+}
+
+/*
+ * UKM = iv|kdf_seed
+ * */
+#define MAX_GOST2015_UKM_SIZE 16
+#define KDF_SEED_SIZE 8
+int gost2015_get_asn1_params(const ASN1_TYPE *params, size_t ukm_size,
+       unsigned char *iv, size_t ukm_offset, unsigned char *kdf_seed)
+{
+  int iv_len = 16;
+  GOST2015_CIPHER_PARAMS *gcp = NULL;
+
+  unsigned char *p = NULL;
+
+  memset(iv, 0, iv_len);
+
+  /* Проверяем тип params */
+  if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
+      GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
+      return 0;
+  }
+
+  p = params->value.sequence->data;
+  /* Извлекаем структуру параметров */
+  gcp = d2i_GOST2015_CIPHER_PARAMS(NULL, (const unsigned char **)&p, params->value.sequence->length);
+  if (gcp == NULL) {
+      GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
+      return 0;
+  }
+
+  /* Проверяем длину синхропосылки */
+  if (gcp->ukm->length != (int)ukm_size) {
+      GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
+      GOST2015_CIPHER_PARAMS_free(gcp);
+      return 0;
+  }
+
+  memcpy(iv, gcp->ukm->data, ukm_offset);
+  memcpy(kdf_seed, gcp->ukm->data+ukm_offset, KDF_SEED_SIZE);
+
+  GOST2015_CIPHER_PARAMS_free(gcp);
+  return 1;
+}
+
+int gost2015_set_asn1_params(ASN1_TYPE *params,
+       const unsigned char *iv, size_t iv_size, const unsigned char *kdf_seed)
+{
+       GOST2015_CIPHER_PARAMS *gcp = GOST2015_CIPHER_PARAMS_new();
+       int ret = 0, len = 0;
+
+       ASN1_OCTET_STRING *os = NULL;
+       unsigned char ukm_buf[MAX_GOST2015_UKM_SIZE];
+       unsigned char *buf = NULL;
+
+       if (gcp == NULL) {
+           GOSTerr(GOST_F_GOST2015_SET_ASN1_PARAMS, ERR_R_MALLOC_FAILURE);
+                       return 0;
+       }
+
+       memcpy(ukm_buf, iv, iv_size);
+       memcpy(ukm_buf+iv_size, kdf_seed, KDF_SEED_SIZE);
+
+       if (ASN1_STRING_set(gcp->ukm, ukm_buf, iv_size + KDF_SEED_SIZE) == 0) {
+           GOSTerr(GOST_F_GOST2015_SET_ASN1_PARAMS, ERR_R_MALLOC_FAILURE);
+                       goto end;
+       }
+
+       len = i2d_GOST2015_CIPHER_PARAMS(gcp, &buf);
+
+       if (len <= 0
+           || (os = ASN1_OCTET_STRING_new()) == NULL
+                       || ASN1_OCTET_STRING_set(os, buf, len) == 0) {
+                       goto end;
+       }
+
+       ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
+       ret = 1;
+
+end:
+       OPENSSL_free(buf);
+       if (ret <= 0 && os)
+               ASN1_OCTET_STRING_free(os);
+
+       GOST2015_CIPHER_PARAMS_free(gcp);
+       return ret;
+}
diff --git a/gost_gost2015.h b/gost_gost2015.h
new file mode 100644 (file)
index 0000000..797fbca
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef GOST_GOST2015_H
+#define GOST_GOST2015_H
+
+#include <openssl/evp.h>
+
+#define MAGMA_MAC_MAX_SIZE 8
+#define KUZNYECHIK_MAC_MAX_SIZE 16
+
+int gost2015_final_call(EVP_CIPHER_CTX *ctx, EVP_MD_CTX *omac_ctx, size_t mac_size,
+                       unsigned char *encrypted_mac,
+                       int (*do_cipher) (EVP_CIPHER_CTX *ctx,
+                               unsigned char *out,
+                               const unsigned char *in,
+                               size_t inl));
+
+/* IV is expected to be 16 bytes*/
+int gost2015_get_asn1_params(const ASN1_TYPE *params, size_t ukm_size,
+       unsigned char *iv, size_t ukm_offset, unsigned char *kdf_seed);
+
+int gost2015_set_asn1_params(ASN1_TYPE *params,
+       const unsigned char *iv, size_t iv_size, const unsigned char *kdf_seed);
+#endif
index 9740994a41c45d2c30e9852a32661437df090e60..032886ff4a0e00b6fef87cd7fe54454c9d631f06 100644 (file)
@@ -167,6 +167,12 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
 
+typedef struct {
+       ASN1_OCTET_STRING *ukm;
+       } GOST2015_CIPHER_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(GOST2015_CIPHER_PARAMS)
+
 typedef struct {
     ASN1_OCTET_STRING *masked_priv_key;
     ASN1_OCTET_STRING *public_key;