]> wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
GOST89 key masking 221/head
authorNikolay Morozov <nmorozoff77@yandex.ru>
Fri, 14 Feb 2020 11:28:23 +0000 (14:28 +0300)
committerDmitry Belyavskiy <beldmit@users.noreply.github.com>
Fri, 14 Feb 2020 12:01:09 +0000 (15:01 +0300)
gost89.c
gost89.h

index e84ec91bebc0e12a5d3076ae11f653b35557353e..f940dab384b57cd0ca3ca76400077a498cb49ac5 100644 (file)
--- a/gost89.c
+++ b/gost89.c
@@ -9,6 +9,7 @@
  **********************************************************************/
 #include <string.h>
 #include <openssl/crypto.h>
+#include <openssl/rand.h>
 #include "gost89.h"
 /*-
    Substitution blocks from RFC 4357
@@ -281,41 +282,41 @@ void gostcrypt(gost_ctx * c, const byte * in, byte * out)
     n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
     /* Instead of swapping halves, swap names each round */
 
-    n2 ^= f(c, n1 + c->k[0]);
-    n1 ^= f(c, n2 + c->k[1]);
-    n2 ^= f(c, n1 + c->k[2]);
-    n1 ^= f(c, n2 + c->k[3]);
-    n2 ^= f(c, n1 + c->k[4]);
-    n1 ^= f(c, n2 + c->k[5]);
-    n2 ^= f(c, n1 + c->k[6]);
-    n1 ^= f(c, n2 + c->k[7]);
-
-    n2 ^= f(c, n1 + c->k[0]);
-    n1 ^= f(c, n2 + c->k[1]);
-    n2 ^= f(c, n1 + c->k[2]);
-    n1 ^= f(c, n2 + c->k[3]);
-    n2 ^= f(c, n1 + c->k[4]);
-    n1 ^= f(c, n2 + c->k[5]);
-    n2 ^= f(c, n1 + c->k[6]);
-    n1 ^= f(c, n2 + c->k[7]);
-
-    n2 ^= f(c, n1 + c->k[0]);
-    n1 ^= f(c, n2 + c->k[1]);
-    n2 ^= f(c, n1 + c->k[2]);
-    n1 ^= f(c, n2 + c->k[3]);
-    n2 ^= f(c, n1 + c->k[4]);
-    n1 ^= f(c, n2 + c->k[5]);
-    n2 ^= f(c, n1 + c->k[6]);
-    n1 ^= f(c, n2 + c->k[7]);
-
-    n2 ^= f(c, n1 + c->k[7]);
-    n1 ^= f(c, n2 + c->k[6]);
-    n2 ^= f(c, n1 + c->k[5]);
-    n1 ^= f(c, n2 + c->k[4]);
-    n2 ^= f(c, n1 + c->k[3]);
-    n1 ^= f(c, n2 + c->k[2]);
-    n2 ^= f(c, n1 + c->k[1]);
-    n1 ^= f(c, n2 + c->k[0]);
+    n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
+    n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
+    n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
+    n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
+    n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
+    n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
+    n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
+    n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
+
+    n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
+    n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
+    n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
+    n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
+    n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
+    n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
+    n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
+    n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
+
+    n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
+    n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
+    n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
+    n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
+    n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
+    n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
+    n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
+    n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
+
+    n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
+    n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
+    n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
+    n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
+    n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
+    n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
+    n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
+    n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
 
     out[0] = (byte) (n2 & 0xff);
     out[1] = (byte) ((n2 >> 8) & 0xff);
@@ -334,41 +335,41 @@ void gostdecrypt(gost_ctx * c, const byte * in, byte * out)
     n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24);
     n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
 
-    n2 ^= f(c, n1 + c->k[0]);
-    n1 ^= f(c, n2 + c->k[1]);
-    n2 ^= f(c, n1 + c->k[2]);
-    n1 ^= f(c, n2 + c->k[3]);
-    n2 ^= f(c, n1 + c->k[4]);
-    n1 ^= f(c, n2 + c->k[5]);
-    n2 ^= f(c, n1 + c->k[6]);
-    n1 ^= f(c, n2 + c->k[7]);
-
-    n2 ^= f(c, n1 + c->k[7]);
-    n1 ^= f(c, n2 + c->k[6]);
-    n2 ^= f(c, n1 + c->k[5]);
-    n1 ^= f(c, n2 + c->k[4]);
-    n2 ^= f(c, n1 + c->k[3]);
-    n1 ^= f(c, n2 + c->k[2]);
-    n2 ^= f(c, n1 + c->k[1]);
-    n1 ^= f(c, n2 + c->k[0]);
-
-    n2 ^= f(c, n1 + c->k[7]);
-    n1 ^= f(c, n2 + c->k[6]);
-    n2 ^= f(c, n1 + c->k[5]);
-    n1 ^= f(c, n2 + c->k[4]);
-    n2 ^= f(c, n1 + c->k[3]);
-    n1 ^= f(c, n2 + c->k[2]);
-    n2 ^= f(c, n1 + c->k[1]);
-    n1 ^= f(c, n2 + c->k[0]);
-
-    n2 ^= f(c, n1 + c->k[7]);
-    n1 ^= f(c, n2 + c->k[6]);
-    n2 ^= f(c, n1 + c->k[5]);
-    n1 ^= f(c, n2 + c->k[4]);
-    n2 ^= f(c, n1 + c->k[3]);
-    n1 ^= f(c, n2 + c->k[2]);
-    n2 ^= f(c, n1 + c->k[1]);
-    n1 ^= f(c, n2 + c->k[0]);
+    n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
+    n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
+    n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
+    n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
+    n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
+    n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
+    n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
+    n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
+
+    n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
+    n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
+    n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
+    n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
+    n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
+    n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
+    n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
+    n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
+
+    n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
+    n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
+    n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
+    n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
+    n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
+    n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
+    n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
+    n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
+
+    n2 ^= f(c, n1 + c->key[7] + c->mask[7]);
+    n1 ^= f(c, n2 + c->key[6] + c->mask[6]);
+    n2 ^= f(c, n1 + c->key[5] + c->mask[5]);
+    n1 ^= f(c, n2 + c->key[4] + c->mask[4]);
+    n2 ^= f(c, n1 + c->key[3] + c->mask[3]);
+    n1 ^= f(c, n2 + c->key[2] + c->mask[2]);
+    n2 ^= f(c, n1 + c->key[1] + c->mask[1]);
+    n1 ^= f(c, n2 + c->key[0] + c->mask[0]);
 
     out[0] = (byte) (n2 & 0xff);
     out[1] = (byte) ((n2 >> 8) & 0xff);
@@ -380,6 +381,7 @@ void gostdecrypt(gost_ctx * c, const byte * in, byte * out)
     out[7] = (byte) (n1 >> 24);
 }
 
+
 /* Encrypts several blocks in ECB mode */
 void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks)
 {
@@ -450,10 +452,11 @@ void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock,
 void gost_key(gost_ctx * c, const byte * k)
 {
     int i, j;
-    for (i = 0, j = 0; i < 8; i++, j += 4) {
-        c->k[i] =
-            k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | ((word32) k[j + 3] <<
-                                                         24);
+    RAND_bytes((unsigned char *)c->mask, sizeof(c->mask));
+    for (i = 0, j = 0; i < 8; ++i, j += 4) {
+        c->key[i] =
+            (k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | ((word32) k[j + 3] <<
+                                                         24)) - c->mask[i];
     }
 }
 
@@ -461,10 +464,11 @@ void gost_key(gost_ctx * c, const byte * k)
 void magma_key(gost_ctx * c, const byte * k)
 {
     int i, j;
-    for (i = 0, j = 0; i < 8; i++, j += 4) {
-        c->k[i] =
-            k[j + 3] | (k[j + 2] << 8) | (k[j + 1] << 16) | ((word32) k[j] <<
-                                                             24);
+    RAND_bytes((unsigned char *)c->mask, sizeof(c->mask));
+    for (i = 0, j = 0; i < 8; ++i, j += 4) {
+        c->key[i] =
+            (k[j + 3] | (k[j + 2] << 8) | (k[j + 1] << 16) | ((word32) k[j] <<
+                                                             24))  - c->mask[i];
     }
 }
 
@@ -473,10 +477,10 @@ void gost_get_key(gost_ctx * c, byte * k)
 {
     int i, j;
     for (i = 0, j = 0; i < 8; i++, j += 4) {
-        k[j] = (byte) (c->k[i] & 0xFF);
-        k[j + 1] = (byte) ((c->k[i] >> 8) & 0xFF);
-        k[j + 2] = (byte) ((c->k[i] >> 16) & 0xFF);
-        k[j + 3] = (byte) ((c->k[i] >> 24) & 0xFF);
+        k[j] = (byte)((c->key[i] + c->mask[i]) & 0xFF);
+        k[j+1] = (byte)(((c->key[i] + c->mask[i]) >> 8 )& 0xFF);
+        k[j+2] = (byte)(((c->key[i] + c->mask[i]) >> 16) & 0xFF);
+        k[j+3] = (byte)(((c->key[i] + c->mask[i]) >> 24) & 0xFF);
     }
 }
 
@@ -485,10 +489,10 @@ void magma_get_key(gost_ctx * c, byte * k)
 {
     int i, j;
     for (i = 0, j = 0; i < 8; i++, j += 4) {
-        k[j + 3] = (byte) (c->k[i] & 0xFF);
-        k[j + 2] = (byte) ((c->k[i] >> 8) & 0xFF);
-        k[j + 1] = (byte) ((c->k[i] >> 16) & 0xFF);
-        k[j + 0] = (byte) ((c->k[i] >> 24) & 0xFF);
+        k[j + 3] = (byte) ((c->key[i] + c->mask[i]) & 0xFF);
+        k[j + 2] = (byte) (((c->key[i] + c->mask[i]) >> 8) & 0xFF);
+        k[j + 1] = (byte) (((c->key[i] + c->mask[i]) >> 16) & 0xFF);
+        k[j + 0] = (byte) (((c->key[i] + c->mask[i]) >> 24) & 0xFF);
     }
 }
 
@@ -504,7 +508,8 @@ void gost_init(gost_ctx * c, const gost_subst_block * b)
 /* Cleans up key from context */
 void gost_destroy(gost_ctx * c)
 {
-    OPENSSL_cleanse(c->k, sizeof(c->k));
+    OPENSSL_cleanse(c->key, sizeof(c->key));
+    OPENSSL_cleanse(c->mask, sizeof(c->mask));
 }
 
 /*
@@ -525,23 +530,23 @@ void mac_block(gost_ctx * c, byte * buffer, const byte * block)
                                                              buffer[7] << 24);
     /* Instead of swapping halves, swap names each round */
 
-    n2 ^= f(c, n1 + c->k[0]);
-    n1 ^= f(c, n2 + c->k[1]);
-    n2 ^= f(c, n1 + c->k[2]);
-    n1 ^= f(c, n2 + c->k[3]);
-    n2 ^= f(c, n1 + c->k[4]);
-    n1 ^= f(c, n2 + c->k[5]);
-    n2 ^= f(c, n1 + c->k[6]);
-    n1 ^= f(c, n2 + c->k[7]);
-
-    n2 ^= f(c, n1 + c->k[0]);
-    n1 ^= f(c, n2 + c->k[1]);
-    n2 ^= f(c, n1 + c->k[2]);
-    n1 ^= f(c, n2 + c->k[3]);
-    n2 ^= f(c, n1 + c->k[4]);
-    n1 ^= f(c, n2 + c->k[5]);
-    n2 ^= f(c, n1 + c->k[6]);
-    n1 ^= f(c, n2 + c->k[7]);
+    n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
+    n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
+    n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
+    n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
+    n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
+    n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
+    n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
+    n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
+
+    n2 ^= f(c, n1 + c->key[0] + c->mask[0]);
+    n1 ^= f(c, n2 + c->key[1] + c->mask[1]);
+    n2 ^= f(c, n1 + c->key[2] + c->mask[2]);
+    n1 ^= f(c, n2 + c->key[3] + c->mask[3]);
+    n2 ^= f(c, n1 + c->key[4] + c->mask[4]);
+    n1 ^= f(c, n2 + c->key[5] + c->mask[5]);
+    n2 ^= f(c, n1 + c->key[6] + c->mask[6]);
+    n1 ^= f(c, n2 + c->key[7] + c->mask[7]);
 
     buffer[0] = (byte) (n1 & 0xff);
     buffer[1] = (byte) ((n1 >> 8) & 0xff);
index b8a947e1bdd014cf1a091c5d2745042f771234fc..1dfae9be3c9ecee35b07aeff6d5865fe25c80495 100644 (file)
--- a/gost89.h
+++ b/gost89.h
@@ -33,7 +33,8 @@ typedef struct {
 
 /* Cipher context includes key and preprocessed  substitution block */
 typedef struct {
-    u4 k[8];
+    u4 key[8];
+    u4 mask[8];
     /* Constant s-boxes -- set up in gost_init(). */
     u4 k87[256], k65[256], k43[256], k21[256];
 } gost_ctx;