]> wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
CryptoPro compatibility
authorDmitry Belyavskiy <beldmit@gmail.com>
Thu, 27 Dec 2018 17:39:35 +0000 (20:39 +0300)
committerDmitry Belyavskiy <beldmit@gmail.com>
Thu, 27 Dec 2018 17:39:35 +0000 (20:39 +0300)
gost_grasshopper_cipher.c

index 21d503814e2c037d55e51eef5c8a7c711f70bbbb..050ec7a1838a53ae7bc498e77ae02616eabca55f 100644 (file)
@@ -765,6 +765,7 @@ int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
         {
             unsigned char newkey[32];
             int mode = EVP_CIPHER_CTX_mode(ctx);
+            static const unsigned char zeroseq[8];
             gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
             gost_grasshopper_cipher_ctx *c = NULL;
 
@@ -777,6 +778,38 @@ int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
 
             if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
                              (const unsigned char *)ptr) > 0) {
+            /* FIXME may be it should be moved to separate control */
+              unsigned char adjusted_iv[16];
+              unsigned char seq[8];
+              int j;
+              memcpy(seq, ptr, 8);
+              if (EVP_CIPHER_CTX_encrypting(ctx)) {
+              /*
+               * OpenSSL increments seq on after mac calculation
+               * As we have Mac-Then-Encrypt, we need decrement it here on encryption
+               * to derive the key correctly.
+               * */
+                if (memcmp(seq, zeroseq, 8) != 0)
+                {
+                  for(j=7; j>=0; j--)
+                  {
+                    if (seq[j] != 0) {seq[j]--; break;};
+                  }
+                }
+              }
+
+              memset(adjusted_iv, 0, 16);
+              memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
+              for(j=7; j>=0; j--)
+              {
+                int adj_byte, carry = 0;
+                adj_byte = adjusted_iv[j]+seq[j]+carry;
+                carry = (adj_byte > 255) ? 1 : 0;
+                adjusted_iv[j] = adj_byte & 0xFF;
+              }
+              EVP_CIPHER_CTX_set_num(ctx, 0);
+              memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);
+
                 gost_grasshopper_cipher_key(c, newkey);
                 return 1;
             }