]> www.wagner.pp.ru Git - openssl-gost/engine.git/blobdiff - gost_grasshopper_cipher.c
GOST CMS encryption implementation.
[openssl-gost/engine.git] / gost_grasshopper_cipher.c
index f0419e3029c8f8aa8ebe1d6fdebece9477354d87..2c2ea88119b411dd2d08775a6d035ba01eeae0e2 100644 (file)
@@ -215,6 +215,11 @@ int gost_grasshopper_cipher_init(EVP_CIPHER_CTX *ctx,
 
     if (EVP_CIPHER_CTX_get_app_data(ctx) == NULL) {
         EVP_CIPHER_CTX_set_app_data(ctx, EVP_CIPHER_CTX_get_cipher_data(ctx));
+        if (enc && c->type == GRASSHOPPER_CIPHER_CTRACPKM) {
+            gost_grasshopper_cipher_ctx_ctr *ctr = EVP_CIPHER_CTX_get_cipher_data(ctx);
+            if (init_zero_kdf_seed(ctr->kdf_seed) == 0)
+                return -1;
+        }
     }
 
     if (key != NULL) {
@@ -313,38 +318,24 @@ GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctracpkm_omac(EVP_CIPHER_CTX
        c->section_size = 4096;
 
        if (key) {
-               unsigned char keys[64];
-               const EVP_MD *md = EVP_get_digestbynid(NID_kuznyechik_mac);
-               EVP_PKEY *mac_key;
-
-               if (md == NULL)
-                       return 0;
-
-               if (enc) {
-                       if (RAND_bytes(c->kdf_seed, 8) != 1)
-                               return 0;
-               }
-
-               if (gost_kdftree2012_256(keys, 64, key, 32, (const unsigned char *)"kdf tree", 8, c->kdf_seed, 8, 1) <= 0)
-                       return 0;
-
+               unsigned char cipher_key[32];
                c->omac_ctx = EVP_MD_CTX_new();
-               mac_key = EVP_PKEY_new_mac_key(NID_kuznyechik_mac, NULL, keys+32, 32);
 
-               if (mac_key == NULL || c->omac_ctx == NULL) {
-                       EVP_PKEY_free(mac_key);
-                       return 0;
+               if (c->omac_ctx == NULL) {
+                   GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_INIT_CTRACPKM_OMAC, ERR_R_MALLOC_FAILURE);
+                               return 0;
                }
 
-               if (EVP_DigestInit_ex(c->omac_ctx, md, NULL) <= 0 ||
-                               EVP_DigestSignInit(c->omac_ctx, NULL, md, NULL, mac_key) <= 0) {
-                       EVP_PKEY_free(mac_key);
-                       return 0;
+               if (gost2015_acpkm_omac_init(NID_kuznyechik_mac, enc, key,
+                                c->omac_ctx, cipher_key, c->kdf_seed) != 1) {
+                   EVP_MD_CTX_free(c->omac_ctx);
+                               c->omac_ctx = NULL;
+                   return 0;
                }
-               EVP_PKEY_free(mac_key);
 
-               return gost_grasshopper_cipher_init(ctx, keys, iv, enc);
+               return gost_grasshopper_cipher_init(ctx, cipher_key, iv, enc);
        }
+
        return gost_grasshopper_cipher_init(ctx, key, iv, enc);
 }
 
@@ -819,8 +810,7 @@ GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
        return 0;
 }
 
-int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
-                                void *ptr)
+int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
 {
     switch (type) {
     case EVP_CTRL_RAND_KEY:{
@@ -922,34 +912,16 @@ int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
         }
 #endif
                case EVP_CTRL_PROCESS_UNPROTECTED:
-                               {
-                                       gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
-                                       ASN1_OBJECT *cmsmacobj = NULL;
-                                       if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKMOMAC)
-                                               return -1;
-          cmsmacobj = OBJ_txt2obj(OID_GOST_CMS_MAC, 1);
-                                       if (cmsmacobj == NULL) {
-                                               GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, ERR_R_MALLOC_FAILURE);
-                                               return -1;
-                                       }
-                                       if (arg == 0) /*Decrypting*/ {
-                                               STACK_OF(X509_ATTRIBUTE) *x = ptr;
-                                               ASN1_OCTET_STRING *osExpectedMac = X509at_get0_data_by_OBJ(x,
-                                                               cmsmacobj, -3, V_ASN1_OCTET_STRING);
-                                               ASN1_OBJECT_free(cmsmacobj);
-
-                                               if (ptr == NULL || osExpectedMac ==NULL || osExpectedMac->length != KUZNYECHIK_MAC_MAX_SIZE)
-                                                       return -1;
-
-                                               memcpy(c->tag, osExpectedMac->data, osExpectedMac->length);
-                                               return 1;
-                                       } else {
-                                               STACK_OF(X509_ATTRIBUTE) *x = ptr;
-                                               return (X509at_add1_attr_by_OBJ(&x, cmsmacobj,
-                                                                       V_ASN1_OCTET_STRING, c->tag, KUZNYECHIK_MAC_MAX_SIZE) == NULL) ? -1 : 1;
-                                       }
-                               }
-                       return 1;
+    {
+      STACK_OF(X509_ATTRIBUTE) *x = ptr;
+      gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
+
+      if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKMOMAC)
+        return -1;
+
+      return gost2015_process_unprotected_attributes(x, arg, KUZNYECHIK_MAC_MAX_SIZE, c->tag);
+    }
+    return 1;
     case EVP_CTRL_COPY: {
                        EVP_CIPHER_CTX *out = ptr;