Re: [PATCH 1/6] modes: add functions implementing common code for 64-bit ciphers

2020-07-08 Thread Dmitry Baryshkov
сб, 27 июн. 2020 г. в 22:37, Dmitry Baryshkov :
>
> 64-bit ciphers are old, but it would be good to use common code for
> their implementations.

Gracious ping for this patchset.

>
> Signed-off-by: Dmitry Baryshkov 
> ---
>  src/lib/libcrypto/modes/cbc64.c | 202 
>  src/lib/libcrypto/modes/cfb64.c | 169 ++
>  src/lib/libcrypto/modes/ctr64.c | 174 +++
>  src/lib/libcrypto/modes/modes.h |  26 
>  src/lib/libcrypto/modes/ofb64.c | 119 +++
>  5 files changed, 690 insertions(+)
>  create mode 100644 src/lib/libcrypto/modes/cbc64.c
>  create mode 100644 src/lib/libcrypto/modes/cfb64.c
>  create mode 100644 src/lib/libcrypto/modes/ctr64.c
>  create mode 100644 src/lib/libcrypto/modes/ofb64.c
>
> diff --git a/src/lib/libcrypto/modes/cbc64.c b/src/lib/libcrypto/modes/cbc64.c
> new file mode 100644
> index ..ec65ac5d3468
> --- /dev/null
> +++ b/src/lib/libcrypto/modes/cbc64.c
> @@ -0,0 +1,202 @@
> +/* $OpenBSD: cbc64.c,v 1.4 2015/02/10 09:46:30 miod Exp $ */
> +/* 
> + * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *notice, this list of conditions and the following disclaimer in
> + *the documentation and/or other materials provided with the
> + *distribution.
> + *
> + * 3. All advertising materials mentioning features or use of this
> + *software must display the following acknowledgment:
> + *"This product includes software developed by the OpenSSL Project
> + *for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
> + *
> + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
> + *endorse or promote products derived from this software without
> + *prior written permission. For written permission, please contact
> + *openssl-c...@openssl.org.
> + *
> + * 5. Products derived from this software may not be called "OpenSSL"
> + *nor may "OpenSSL" appear in their names without prior written
> + *permission of the OpenSSL Project.
> + *
> + * 6. Redistributions of any form whatsoever must retain the following
> + *acknowledgment:
> + *"This product includes software developed by the OpenSSL Project
> + *for use in the OpenSSL Toolkit (http://www.openssl.org/)"
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
> + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
> + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> + * OF THE POSSIBILITY OF SUCH DAMAGE.
> + * 
> + *
> + */
> +
> +#include 
> +#include "modes_lcl.h"
> +#include 
> +
> +#ifndef MODES_DEBUG
> +# ifndef NDEBUG
> +#  define NDEBUG
> +# endif
> +#endif
> +
> +#undef STRICT_ALIGNMENT
> +#ifdef __STRICT_ALIGNMENT
> +#define STRICT_ALIGNMENT 1
> +#else
> +#define STRICT_ALIGNMENT 0
> +#endif
> +
> +void CRYPTO_cbc64_encrypt(const unsigned char *in, unsigned char *out,
> +   size_t len, const void *key,
> +   unsigned char ivec[8], block64_f block)
> +{
> +   size_t n;
> +   const unsigned char *iv = ivec;
> +
> +#if !defined(OPENSSL_SMALL_FOOTPRINT)
> +   if (STRICT_ALIGNMENT &&
> +   ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
> +   while (len>=8) {
> +   for(n=0; n<8; ++n)
> +   out[n] = in[n] ^ iv[n];
> +   (*block)(out, out, key);

Re: [PATCH 1/5] gost: populate params tables with new curves

2020-07-08 Thread Dmitry Baryshkov
Gracious ping for these patches.

сб, 27 июн. 2020 г. в 20:14, Dmitry Baryshkov :
>
> Allow users to specify new curves via strings.
>
> Sponsored by ROSA Linux
>
> Signed-off-by: Dmitry Baryshkov 
> ---
>  src/lib/libcrypto/gost/gostr341001_params.c | 10 ++
>  1 file changed, 10 insertions(+)
>
> diff --git a/src/lib/libcrypto/gost/gostr341001_params.c 
> b/src/lib/libcrypto/gost/gostr341001_params.c
> index 282a21041999..9764964cdc1e 100644
> --- a/src/lib/libcrypto/gost/gostr341001_params.c
> +++ b/src/lib/libcrypto/gost/gostr341001_params.c
> @@ -94,12 +94,22 @@ static const GostR3410_params GostR3410_256_params[] = {
> { "0",  NID_id_GostR3410_2001_TestParamSet },
> { "XA", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
> { "XB", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
> +   { "TCA", NID_id_tc26_gost_3410_12_256_paramSetA },
> +   { "TCB", NID_id_tc26_gost_3410_12_256_paramSetB },
> +   { "TCC", NID_id_tc26_gost_3410_12_256_paramSetC },
> +   { "TCD", NID_id_tc26_gost_3410_12_256_paramSetD },
> { NULL, NID_undef },
>  };
>
>  static const GostR3410_params GostR3410_512_params[] = {
> { "A",  NID_id_tc26_gost_3410_12_512_paramSetA },
> { "B",  NID_id_tc26_gost_3410_12_512_paramSetB },
> +   { "C",  NID_id_tc26_gost_3410_12_512_paramSetC },
> +   { "0",  NID_id_tc26_gost_3410_12_512_paramSetTest},
> +   /* Duplicates for compatibility with OpenSSL */
> +   { "TCA", NID_id_tc26_gost_3410_12_512_paramSetA },
> +   { "TCB", NID_id_tc26_gost_3410_12_512_paramSetB },
> +   { "TCC", NID_id_tc26_gost_3410_12_512_paramSetC },
> { NULL, NID_undef },
>  };
>
> --
> 2.27.0
>


-- 
With best wishes
Dmitry



[PATCH 4/6] crypto: IDEA: convert to use new modes 64-bit helpers

2020-06-27 Thread Dmitry Baryshkov
Convert IDEA cipher to use 64-bit modes helper functions.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/idea/i_cbc.c   | 74 +++-
 src/lib/libcrypto/idea/i_cfb64.c | 57 ++--
 src/lib/libcrypto/idea/i_ofb64.c | 47 ++--
 3 files changed, 13 insertions(+), 165 deletions(-)

diff --git a/src/lib/libcrypto/idea/i_cbc.c b/src/lib/libcrypto/idea/i_cbc.c
index 5bb9640c3403..556a4aa5cbf3 100644
--- a/src/lib/libcrypto/idea/i_cbc.c
+++ b/src/lib/libcrypto/idea/i_cbc.c
@@ -57,81 +57,17 @@
  */
 
 #include 
+#include 
 #include "idea_lcl.h"
 
 void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
 IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int encrypt)
-   {
-   unsigned long tin0,tin1;
-   unsigned long tout0,tout1,xor0,xor1;
-   long l=length;
-   unsigned long tin[2];
-
+{
if (encrypt)
-   {
-   n2l(iv,tout0);
-   n2l(iv,tout1);
-   iv-=8;
-   for (l-=8; l>=0; l-=8)
-   {
-   n2l(in,tin0);
-   n2l(in,tin1);
-   tin0^=tout0;
-   tin1^=tout1;
-   tin[0]=tin0;
-   tin[1]=tin1;
-   idea_encrypt(tin,ks);
-   tout0=tin[0]; l2n(tout0,out);
-   tout1=tin[1]; l2n(tout1,out);
-   }
-   if (l != -8)
-   {
-   n2ln(in,tin0,tin1,l+8);
-   tin0^=tout0;
-   tin1^=tout1;
-   tin[0]=tin0;
-   tin[1]=tin1;
-   idea_encrypt(tin,ks);
-   tout0=tin[0]; l2n(tout0,out);
-   tout1=tin[1]; l2n(tout1,out);
-   }
-   l2n(tout0,iv);
-   l2n(tout1,iv);
-   }
+   CRYPTO_cbc64_encrypt(in, out, length, ks, iv, 
(block64_f)idea_ecb_encrypt);
else
-   {
-   n2l(iv,xor0);
-   n2l(iv,xor1);
-   iv-=8;
-   for (l-=8; l>=0; l-=8)
-   {
-   n2l(in,tin0); tin[0]=tin0;
-   n2l(in,tin1); tin[1]=tin1;
-   idea_encrypt(tin,ks);
-   tout0=tin[0]^xor0;
-   tout1=tin[1]^xor1;
-   l2n(tout0,out);
-   l2n(tout1,out);
-   xor0=tin0;
-   xor1=tin1;
-   }
-   if (l != -8)
-   {
-   n2l(in,tin0); tin[0]=tin0;
-   n2l(in,tin1); tin[1]=tin1;
-   idea_encrypt(tin,ks);
-   tout0=tin[0]^xor0;
-   tout1=tin[1]^xor1;
-   l2nn(tout0,tout1,out,l+8);
-   xor0=tin0;
-   xor1=tin1;
-   }
-   l2n(xor0,iv);
-   l2n(xor1,iv);
-   }
-   tin0=tin1=tout0=tout1=xor0=xor1=0;
-   tin[0]=tin[1]=0;
-   }
+   CRYPTO_cbc64_decrypt(in, out, length, ks, iv, 
(block64_f)idea_ecb_encrypt);
+}
 
 void idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key)
{
diff --git a/src/lib/libcrypto/idea/i_cfb64.c b/src/lib/libcrypto/idea/i_cfb64.c
index b979aaef8669..a74b50d82309 100644
--- a/src/lib/libcrypto/idea/i_cfb64.c
+++ b/src/lib/libcrypto/idea/i_cfb64.c
@@ -57,6 +57,7 @@
  */
 
 #include 
+#include 
 #include "idea_lcl.h"
 
 /* The input and output encrypted as though 64bit cfb mode is being
@@ -67,56 +68,6 @@
 void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
long length, IDEA_KEY_SCHEDULE *schedule,
unsigned char *ivec, int *num, int encrypt)
-   {
-   unsigned long v0,v1,t;
-   int n= *num;
-   long l=length;
-   unsigned long ti[2];
-   unsigned char *iv,c,cc;
-
-   iv=(unsigned char *)ivec;
-   if (encrypt)
-   {
-   while (l--)
-   {
-   if (n == 0)
-   {
-   n2l(iv,v0); ti[0]=v0;
-   n2l(iv,v1); ti[1]=v1;
-   idea_encrypt((unsigned long *)ti,schedule);
-   iv=(unsigned char *)ivec;
-   t=ti[0]; l2n(t,iv);
-   t=ti[1]; l2n(t,iv);
-   iv=(unsigned char *)ivec;
-   }
-   c= *(in++)^iv[n];
-   *(out++)=c;
-   iv[n]=c;
- 

[PATCH 6/6] crypto: Gost 28147-89: convert to use new modes 64-bit helpers

2020-06-27 Thread Dmitry Baryshkov
Convert Gost 28147-89 cipher to use 64-bit modes helper functions.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gost2814789.c | 121 ++-
 1 file changed, 9 insertions(+), 112 deletions(-)

diff --git a/src/lib/libcrypto/gost/gost2814789.c 
b/src/lib/libcrypto/gost/gost2814789.c
index e285413ed460..bbd578ef7010 100644
--- a/src/lib/libcrypto/gost/gost2814789.c
+++ b/src/lib/libcrypto/gost/gost2814789.c
@@ -56,6 +56,7 @@
 #ifndef OPENSSL_NO_GOST
 #include 
 #include 
+#include 
 
 #include "gost_locl.h"
 
@@ -181,15 +182,17 @@ Gost2814789_ecb_encrypt(const unsigned char *in, unsigned 
char *out,
 }
 
 static inline void
-Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *key)
+Gost2814789_encrypt_mesh(const unsigned char *in, unsigned char *out, 
GOST2814789_KEY *key)
 {
if (key->key_meshing && key->count == 1024) {
Gost2814789_cryptopro_key_mesh(key);
-   Gost2814789_encrypt(iv, iv, key);
-   key->count = 0;
+   Gost2814789_encrypt(in, out, key);
+   Gost2814789_encrypt(out, out, key);
+   key->count = 8;
+   } else {
+   Gost2814789_encrypt(in, out, key);
+   key->count += 8;
}
-   Gost2814789_encrypt(iv, iv, key);
-   key->count += 8;
 }
 
 static inline void
@@ -209,113 +212,7 @@ Gost2814789_cfb64_encrypt(const unsigned char *in, 
unsigned char *out,
 size_t len, GOST2814789_KEY *key, unsigned char *ivec, int *num,
 const int enc)
 {
-   unsigned int n;
-   size_t l = 0;
-
-   n = *num;
-
-   if (enc) {
-#if !defined(OPENSSL_SMALL_FOOTPRINT)
-   if (8 % sizeof(size_t) == 0) do { /* always true actually */
-   while (n && len) {
-   *(out++) = ivec[n] ^= *(in++);
-   --len;
-   n = (n + 1) % 8;
-   }
-#ifdef __STRICT_ALIGNMENT
-   if (((size_t)in | (size_t)out | (size_t)ivec) %
-   sizeof(size_t) != 0)
-   break;
-#endif
-   while (len >= 8) {
-   Gost2814789_encrypt_mesh(ivec, key);
-   for (; n < 8; n += sizeof(size_t)) {
-   *(size_t*)(out + n) =
-   *(size_t*)(ivec + n) ^=
-   *(size_t*)(in + n);
-   }
-   len -= 8;
-   out += 8;
-   in  += 8;
-   n = 0;
-   }
-   if (len) {
-   Gost2814789_encrypt_mesh(ivec, key);
-   while (len--) {
-   out[n] = ivec[n] ^= in[n];
-   ++n;
-   }
-   }
-   *num = n;
-   return;
-   } while (0);
-   /* the rest would be commonly eliminated by x86* compiler */
-#endif
-   while (l= 8) {
-   Gost2814789_encrypt_mesh(ivec, key);
-   for (; n < 8; n += sizeof(size_t)) {
-   size_t t = *(size_t*)(in + n);
-   *(size_t*)(out + n) =
-   *(size_t*)(ivec + n) ^ t;
-   *(size_t*)(ivec + n) = t;
-   }
-   len -= 8;
-   out += 8;
-   in  += 8;
-   n = 0;
-   }
-   if (len) {
-   Gost2814789_encrypt_mesh(ivec, key);
-   while (len--) {
-   unsigned char c;
-
-   out[n] = ivec[n] ^ (c = in[n]);
-   ivec[n] = c;
-   ++n;
-   }
-   }
-   *num = n;
-   return;
-   } while (0);
-   /* the rest would be commonly eliminated by x86* compiler */
-#endif
-   while (l < len) {
-   unsigned char c;
-
-   if (n == 0) {
-   Gost2814789_encrypt_mesh(ivec, key);
-   }
-   out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
-   ++l;
-   n = (n + 1) % 8;
-   }
-   *num = n;

[PATCH 1/6] modes: add functions implementing common code for 64-bit ciphers

2020-06-27 Thread Dmitry Baryshkov
64-bit ciphers are old, but it would be good to use common code for
their implementations.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/modes/cbc64.c | 202 
 src/lib/libcrypto/modes/cfb64.c | 169 ++
 src/lib/libcrypto/modes/ctr64.c | 174 +++
 src/lib/libcrypto/modes/modes.h |  26 
 src/lib/libcrypto/modes/ofb64.c | 119 +++
 5 files changed, 690 insertions(+)
 create mode 100644 src/lib/libcrypto/modes/cbc64.c
 create mode 100644 src/lib/libcrypto/modes/cfb64.c
 create mode 100644 src/lib/libcrypto/modes/ctr64.c
 create mode 100644 src/lib/libcrypto/modes/ofb64.c

diff --git a/src/lib/libcrypto/modes/cbc64.c b/src/lib/libcrypto/modes/cbc64.c
new file mode 100644
index ..ec65ac5d3468
--- /dev/null
+++ b/src/lib/libcrypto/modes/cbc64.c
@@ -0,0 +1,202 @@
+/* $OpenBSD: cbc64.c,v 1.4 2015/02/10 09:46:30 miod Exp $ */
+/* 
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in
+ *the documentation and/or other materials provided with the
+ *distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *software must display the following acknowledgment:
+ *"This product includes software developed by the OpenSSL Project
+ *for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *endorse or promote products derived from this software without
+ *prior written permission. For written permission, please contact
+ *openssl-c...@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *nor may "OpenSSL" appear in their names without prior written
+ *permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *acknowledgment:
+ *"This product includes software developed by the OpenSSL Project
+ *for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ *
+ */
+
+#include 
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+#undef STRICT_ALIGNMENT
+#ifdef __STRICT_ALIGNMENT
+#define STRICT_ALIGNMENT 1
+#else
+#define STRICT_ALIGNMENT 0
+#endif
+
+void CRYPTO_cbc64_encrypt(const unsigned char *in, unsigned char *out,
+   size_t len, const void *key,
+   unsigned char ivec[8], block64_f block)
+{
+   size_t n;
+   const unsigned char *iv = ivec;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+   if (STRICT_ALIGNMENT &&
+   ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+   while (len>=8) {
+   for(n=0; n<8; ++n)
+   out[n] = in[n] ^ iv[n];
+   (*block)(out, out, key);
+   iv = out;
+   len -= 8;
+   in  += 8;
+   out += 8;
+   }
+   } else {
+   while (len>=8) {
+   for(n=0; n<8; n+=sizeof(size_t))
+   *(size_t*)(out+n) =
+   *(size_t*)(in+n) ^ *(size_t*)(iv+n);
+   (*block)(out, out, key);
+   iv = out;
+   len -= 8;
+   in  += 8;
+   out += 8;
+   }
+   }
+#endif
+   while (len) {
+ 

[PATCH 5/6] crypto: RC2: convert to use new modes 64-bit helpers

2020-06-27 Thread Dmitry Baryshkov
Convert RC2 cipher to use 64-bit modes helper functions.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/rc2/rc2.h  |   4 +-
 src/lib/libcrypto/rc2/rc2_cbc.c  | 111 +++
 src/lib/libcrypto/rc2/rc2_locl.h |   7 ++
 src/lib/libcrypto/rc2/rc2cfb64.c |  57 ++--
 src/lib/libcrypto/rc2/rc2ofb64.c |  47 ++---
 5 files changed, 55 insertions(+), 171 deletions(-)

diff --git a/src/lib/libcrypto/rc2/rc2.h b/src/lib/libcrypto/rc2/rc2.h
index 21511ff36ead..03df1433cc22 100644
--- a/src/lib/libcrypto/rc2/rc2.h
+++ b/src/lib/libcrypto/rc2/rc2.h
@@ -83,8 +83,8 @@ typedef struct rc2_key_st
 void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
 void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key,
 int enc);
-void RC2_encrypt(unsigned long *data,RC2_KEY *key);
-void RC2_decrypt(unsigned long *data,RC2_KEY *key);
+void RC2_encrypt(unsigned long *data,const RC2_KEY *key);
+void RC2_decrypt(unsigned long *data,const RC2_KEY *key);
 void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
RC2_KEY *ks, unsigned char *iv, int enc);
 void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
diff --git a/src/lib/libcrypto/rc2/rc2_cbc.c b/src/lib/libcrypto/rc2/rc2_cbc.c
index a947f1d3c3a1..276f3b3b4d61 100644
--- a/src/lib/libcrypto/rc2/rc2_cbc.c
+++ b/src/lib/libcrypto/rc2/rc2_cbc.c
@@ -57,86 +57,22 @@
  */
 
 #include 
+#include 
 #include "rc2_locl.h"
 
 void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
 RC2_KEY *ks, unsigned char *iv, int encrypt)
-   {
-   unsigned long tin0,tin1;
-   unsigned long tout0,tout1,xor0,xor1;
-   long l=length;
-   unsigned long tin[2];
-
+{
if (encrypt)
-   {
-   c2l(iv,tout0);
-   c2l(iv,tout1);
-   iv-=8;
-   for (l-=8; l>=0; l-=8)
-   {
-   c2l(in,tin0);
-   c2l(in,tin1);
-   tin0^=tout0;
-   tin1^=tout1;
-   tin[0]=tin0;
-   tin[1]=tin1;
-   RC2_encrypt(tin,ks);
-   tout0=tin[0]; l2c(tout0,out);
-   tout1=tin[1]; l2c(tout1,out);
-   }
-   if (l != -8)
-   {
-   c2ln(in,tin0,tin1,l+8);
-   tin0^=tout0;
-   tin1^=tout1;
-   tin[0]=tin0;
-   tin[1]=tin1;
-   RC2_encrypt(tin,ks);
-   tout0=tin[0]; l2c(tout0,out);
-   tout1=tin[1]; l2c(tout1,out);
-   }
-   l2c(tout0,iv);
-   l2c(tout1,iv);
-   }
+   CRYPTO_cbc64_encrypt(in, out, length, ks, iv, 
(block64_f)RC2_block_encrypt);
else
-   {
-   c2l(iv,xor0);
-   c2l(iv,xor1);
-   iv-=8;
-   for (l-=8; l>=0; l-=8)
-   {
-   c2l(in,tin0); tin[0]=tin0;
-   c2l(in,tin1); tin[1]=tin1;
-   RC2_decrypt(tin,ks);
-   tout0=tin[0]^xor0;
-   tout1=tin[1]^xor1;
-   l2c(tout0,out);
-   l2c(tout1,out);
-   xor0=tin0;
-   xor1=tin1;
-   }
-   if (l != -8)
-   {
-   c2l(in,tin0); tin[0]=tin0;
-   c2l(in,tin1); tin[1]=tin1;
-   RC2_decrypt(tin,ks);
-   tout0=tin[0]^xor0;
-   tout1=tin[1]^xor1;
-   l2cn(tout0,tout1,out,l+8);
-   xor0=tin0;
-   xor1=tin1;
-   }
-   l2c(xor0,iv);
-   l2c(xor1,iv);
-   }
-   tin0=tin1=tout0=tout1=xor0=xor1=0;
-   tin[0]=tin[1]=0;
-   }
+   CRYPTO_cbc64_decrypt(in, out, length, ks, iv, 
(block64_f)RC2_block_decrypt);
+}
 
-void RC2_encrypt(unsigned long *d, RC2_KEY *key)
+void RC2_encrypt(unsigned long *d, const RC2_KEY *key)
{
int i,n;
-   RC2_INT *p0,*p1;
+   const RC2_INT *p0,*p1;
RC2_INT x0,x1,x2,x3,t;
unsigned long l;
 
@@ -178,10 +114,10 @@ void RC2_encrypt(unsigned long *d, RC2_KEY *key)
d[1]=(unsigned long)(x2&0x)|((unsigned long)(x3&0x)<<16L);
}
 
-void RC2_decrypt(unsigned long *d, RC2_KEY *key)
+void RC2_decrypt(unsigned long *d, const RC2_KEY *key)
{
int i,n;
-   RC2_INT *p0,*p1;
+   const RC2_INT *p0,*p1;
RC2_INT x0,x1,x2,x3,t;
unsigned long l;
 
@@ -224,3 +160,32 @@ void RC2_dec

[PATCH 3/6] crypto: cast: convert to use new modes 64-bit helpers

2020-06-27 Thread Dmitry Baryshkov
Convert CAST cipher to use 64-bit modes helper functions.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/Makefile|   2 +-
 src/lib/libcrypto/cast/c_cbc.c|  75 +
 src/lib/libcrypto/cast/c_cfb64.c  |  56 ++--
 src/lib/libcrypto/cast/c_enc.c| 108 --
 src/lib/libcrypto/cast/c_ofb64.c  |  46 ++---
 src/lib/libcrypto/cast/cast_lcl.h |   8 +++
 6 files changed, 120 insertions(+), 175 deletions(-)
 create mode 100644 src/lib/libcrypto/cast/c_cbc.c

diff --git a/src/lib/libcrypto/Makefile b/src/lib/libcrypto/Makefile
index 291af21965bf..2e20904ab840 100644
--- a/src/lib/libcrypto/Makefile
+++ b/src/lib/libcrypto/Makefile
@@ -89,7 +89,7 @@ SRCS+= buffer.c buf_err.c buf_str.c
 SRCS+= cmll_cfb.c cmll_ctr.c cmll_ecb.c cmll_ofb.c
 
 # cast/
-SRCS+= c_skey.c c_ecb.c c_enc.c c_cfb64.c c_ofb64.c
+SRCS+= c_skey.c c_ecb.c c_enc.c c_cfb64.c c_ofb64.c c_cbc.c
 
 # chacha/
 SRCS+= chacha.c
diff --git a/src/lib/libcrypto/cast/c_cbc.c b/src/lib/libcrypto/cast/c_cbc.c
new file mode 100644
index ..1dc32ad8ca54
--- /dev/null
+++ b/src/lib/libcrypto/cast/c_cbc.c
@@ -0,0 +1,75 @@
+/* $OpenBSD: c_cbc.c,v 1.5 2014/10/28 07:35:58 jsg Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (e...@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (e...@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (t...@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *must display the following acknowledgement:
+ *"This product includes cryptographic software written by
+ * Eric Young (e...@cryptsoft.com)"
+ *The word 'cryptographic' can be left out if the rouines from the library
+ *being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *the apps directory (application code) you must include an 
acknowledgement:
+ *"This product includes software written by Tim Hudson 
(t...@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include "cast_lcl.h"
+
+/* The input and output encrypted as though 64bit cbc mode is being
+ * used.
+ */
+
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out,
+   long length, const CAST_KEY *schedule, unsigned char 
*ivec,
+   int enc)
+{
+   if (enc)
+   CRYPTO_cbc64_encrypt(in, out, length, schedule, ivec, 
(block64_f)CAST_block_encrypt);
+   else
+   CRYPTO_cbc64_decrypt(i

[PATCH 2/6] crypto: bf: convert to use new modes 64-bit helpers

2020-06-27 Thread Dmitry Baryshkov
Convert Blowfish cipher to use 64-bit modes helper functions.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/Makefile  |   2 +-
 src/lib/libcrypto/bf/bf_cbc.c   |  83 ++-
 src/lib/libcrypto/bf/bf_cfb64.c |  57 ++--
 src/lib/libcrypto/bf/bf_enc.c   | 114 
 src/lib/libcrypto/bf/bf_locl.h  |   8 +++
 src/lib/libcrypto/bf/bf_ofb64.c |  47 ++---
 6 files changed, 51 insertions(+), 260 deletions(-)

diff --git a/src/lib/libcrypto/Makefile b/src/lib/libcrypto/Makefile
index 9207b93f321d..291af21965bf 100644
--- a/src/lib/libcrypto/Makefile
+++ b/src/lib/libcrypto/Makefile
@@ -65,7 +65,7 @@ SRCS+= evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c 
asn_moid.c
 SRCS+= a_time_tm.c
 
 # bf/
-SRCS+= bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c
+SRCS+= bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c bf_cbc.c
 
 # bio/
 SRCS+= bio_lib.c bio_cb.c bio_err.c bio_meth.c
diff --git a/src/lib/libcrypto/bf/bf_cbc.c b/src/lib/libcrypto/bf/bf_cbc.c
index 6f45f9ae4c35..a9d3cf6d5541 100644
--- a/src/lib/libcrypto/bf/bf_cbc.c
+++ b/src/lib/libcrypto/bf/bf_cbc.c
@@ -57,87 +57,14 @@
  */
 
 #include 
+#include 
 #include "bf_locl.h"
 
 void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
 const BF_KEY *schedule, unsigned char *ivec, int encrypt)
-   {
-   BF_LONG tin0,tin1;
-   BF_LONG tout0,tout1,xor0,xor1;
-   long l=length;
-   BF_LONG tin[2];
-
+{
if (encrypt)
-   {
-   n2l(ivec,tout0);
-   n2l(ivec,tout1);
-   ivec-=8;
-   for (l-=8; l>=0; l-=8)
-   {
-   n2l(in,tin0);
-   n2l(in,tin1);
-   tin0^=tout0;
-   tin1^=tout1;
-   tin[0]=tin0;
-   tin[1]=tin1;
-   BF_encrypt(tin,schedule);
-   tout0=tin[0];
-   tout1=tin[1];
-   l2n(tout0,out);
-   l2n(tout1,out);
-   }
-   if (l != -8)
-   {
-   n2ln(in,tin0,tin1,l+8);
-   tin0^=tout0;
-   tin1^=tout1;
-   tin[0]=tin0;
-   tin[1]=tin1;
-   BF_encrypt(tin,schedule);
-   tout0=tin[0];
-   tout1=tin[1];
-   l2n(tout0,out);
-   l2n(tout1,out);
-   }
-   l2n(tout0,ivec);
-   l2n(tout1,ivec);
-   }
+   CRYPTO_cbc64_encrypt(in, out, length, schedule, ivec, 
(block64_f)BF_block_encrypt);
else
-   {
-   n2l(ivec,xor0);
-   n2l(ivec,xor1);
-   ivec-=8;
-   for (l-=8; l>=0; l-=8)
-   {
-   n2l(in,tin0);
-   n2l(in,tin1);
-   tin[0]=tin0;
-   tin[1]=tin1;
-   BF_decrypt(tin,schedule);
-   tout0=tin[0]^xor0;
-   tout1=tin[1]^xor1;
-   l2n(tout0,out);
-   l2n(tout1,out);
-   xor0=tin0;
-   xor1=tin1;
-   }
-   if (l != -8)
-   {
-   n2l(in,tin0);
-   n2l(in,tin1);
-   tin[0]=tin0;
-   tin[1]=tin1;
-   BF_decrypt(tin,schedule);
-   tout0=tin[0]^xor0;
-   tout1=tin[1]^xor1;
-   l2nn(tout0,tout1,out,l+8);
-   xor0=tin0;
-   xor1=tin1;
-   }
-   l2n(xor0,ivec);
-   l2n(xor1,ivec);
-   }
-   tin0=tin1=tout0=tout1=xor0=xor1=0;
-   tin[0]=tin[1]=0;
-   }
-
+   CRYPTO_cbc64_decrypt(in, out, length, schedule, ivec, 
(block64_f)BF_block_decrypt);
+}
diff --git a/src/lib/libcrypto/bf/bf_cfb64.c b/src/lib/libcrypto/bf/bf_cfb64.c
index 6cc0bb999bd3..463080cb230f 100644
--- a/src/lib/libcrypto/bf/bf_cfb64.c
+++ b/src/lib/libcrypto/bf/bf_cfb64.c
@@ -57,6 +57,7 @@
  */
 
 #include 
+#include 
 #include "bf_locl.h"
 
 /* The input and output encrypted as though 64bit cfb mode is being
@@ -66,56 +67,6 @@
 
 void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
 const BF_KEY *schedule, unsigned char *ivec, int *num, int encrypt)
-   {
-   BF_LONG v0,v1,t;
-   int n= *num;
-   long l=length;
-   BF_LONG ti[2];
-   unsigned char *iv,c,cc;
-
-   iv=(unsigned char *)ivec;
-   if (encrypt)
-   

[PATCH 5/5] pkcs12: add support for GOST PFX files

2020-06-27 Thread Dmitry Baryshkov
Russian standard body has changed the way MAC key is calculated for
PKCS12 files. Generate proper keys depending on the digest type used for
MAC generation.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/pkcs12/p12_key.c  | 18 ++
 src/lib/libcrypto/pkcs12/p12_mutl.c | 28 +---
 src/lib/libcrypto/pkcs12/pkcs12.h   |  5 +
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/src/lib/libcrypto/pkcs12/p12_key.c 
b/src/lib/libcrypto/pkcs12/p12_key.c
index d419a9d83598..9a5297a23131 100644
--- a/src/lib/libcrypto/pkcs12/p12_key.c
+++ b/src/lib/libcrypto/pkcs12/p12_key.c
@@ -195,3 +195,21 @@ end:
EVP_MD_CTX_cleanup();
return ret;
 }
+
+int
+PKCS12_key_gen_gost(const char *pass, int passlen, unsigned char *salt,
+int saltlen, int iter, int n, unsigned char *out,
+const EVP_MD *md_type)
+{
+   unsigned char buf[96];
+
+   if (n != PKCS12_GOST_KEY_LEN)
+   return 0;
+
+   if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, md_type, 
sizeof(buf), buf))
+   return 0;
+
+   memcpy(out, buf + sizeof(buf) - PKCS12_GOST_KEY_LEN, 
PKCS12_GOST_KEY_LEN);
+
+   return 1;
+}
diff --git a/src/lib/libcrypto/pkcs12/p12_mutl.c 
b/src/lib/libcrypto/pkcs12/p12_mutl.c
index f3132ec75f68..023bbbd92db1 100644
--- a/src/lib/libcrypto/pkcs12/p12_mutl.c
+++ b/src/lib/libcrypto/pkcs12/p12_mutl.c
@@ -74,6 +74,7 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
 unsigned char *mac, unsigned int *maclen)
 {
const EVP_MD *md_type;
+   int md_type_nid;
HMAC_CTX hmac;
unsigned char key[EVP_MAX_MD_SIZE], *salt;
int saltlen, iter;
@@ -97,13 +98,26 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
PKCS12error(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
return 0;
}
-   md_size = EVP_MD_size(md_type);
-   if (md_size < 0)
-   return 0;
-   if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
-   md_size, key, md_type)) {
-   PKCS12error(PKCS12_R_KEY_GEN_ERROR);
-   return 0;
+   md_type_nid = EVP_MD_type(md_type);
+   if ((md_type_nid == NID_id_GostR3411_94 ||
+md_type_nid == NID_id_tc26_gost3411_2012_256 ||
+md_type_nid == NID_id_tc26_gost3411_2012_512) &&
+   getenv("LEGACY_GOST_PKCS12") == NULL) {
+   md_size = PKCS12_GOST_KEY_LEN;
+   if (!PKCS12_key_gen_gost(pass, passlen, salt, saltlen, iter,
+   md_size, key, md_type)) {
+   PKCS12error(PKCS12_R_KEY_GEN_ERROR);
+   return 0;
+   }
+   } else {
+   md_size = EVP_MD_size(md_type);
+   if (md_size < 0)
+   return 0;
+   if (!PKCS12_key_gen(pass, passlen, salt, saltlen, 
PKCS12_MAC_ID, iter,
+   md_size, key, md_type)) {
+   PKCS12error(PKCS12_R_KEY_GEN_ERROR);
+   return 0;
+   }
}
HMAC_CTX_init();
if (!HMAC_Init_ex(, key, md_size, md_type, NULL) ||
diff --git a/src/lib/libcrypto/pkcs12/pkcs12.h 
b/src/lib/libcrypto/pkcs12/pkcs12.h
index 56635f9d7e0a..4dab109bbc3a 100644
--- a/src/lib/libcrypto/pkcs12/pkcs12.h
+++ b/src/lib/libcrypto/pkcs12/pkcs12.h
@@ -91,6 +91,11 @@ extern "C" {
 #define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
 #endif
 
+#define PKCS12_GOST_KEY_LEN 32
+int PKCS12_key_gen_gost(const char *pass, int passlen, unsigned char *salt,
+int saltlen, int iter, int n, unsigned char *out,
+const EVP_MD *md_type);
+
 /* MS key usage constants */
 
 #define KEY_EX 0x10
-- 
2.27.0



[PATCH 3/5] gost: support new PublicKeyParameters format

2020-06-27 Thread Dmitry Baryshkov
Add support for updated PublicKeyParameters format as defined by
draft-deremin-rfc4491-bis.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gost_asn1.c |  2 +-
 src/lib/libcrypto/gost/gostr341001_ameth.c | 42 --
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/src/lib/libcrypto/gost/gost_asn1.c 
b/src/lib/libcrypto/gost/gost_asn1.c
index 2652162777b7..703d64070449 100644
--- a/src/lib/libcrypto/gost/gost_asn1.c
+++ b/src/lib/libcrypto/gost/gost_asn1.c
@@ -190,7 +190,7 @@ static const ASN1_TEMPLATE GOST_KEY_PARAMS_seq_tt[] = {
.item = _OBJECT_it,
},
{
-   .flags = 0,
+   .flags = ASN1_TFLG_OPTIONAL,
.tag = 0,
.offset = offsetof(GOST_KEY_PARAMS, hash_params),
.field_name = "hash_params",
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c 
b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 0e9521178da5..7cb70ed420ae 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -90,9 +90,33 @@ decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned 
char **p, int len)
return 0;
}
param_nid = OBJ_obj2nid(gkp->key_params);
-   digest_nid = OBJ_obj2nid(gkp->hash_params);
+   if (gkp->hash_params)
+   digest_nid = OBJ_obj2nid(gkp->hash_params);
+   else {
+   switch (param_nid) {
+   case NID_id_tc26_gost_3410_12_256_paramSetA:
+   case NID_id_tc26_gost_3410_12_256_paramSetB:
+   case NID_id_tc26_gost_3410_12_256_paramSetC:
+   case NID_id_tc26_gost_3410_12_256_paramSetD:
+   digest_nid = NID_id_tc26_gost3411_2012_256;
+   break;
+   case NID_id_tc26_gost_3410_12_512_paramSetTest:
+   case NID_id_tc26_gost_3410_12_512_paramSetA:
+   case NID_id_tc26_gost_3410_12_512_paramSetB:
+   case NID_id_tc26_gost_3410_12_512_paramSetC:
+   digest_nid = NID_id_tc26_gost3411_2012_512;
+   break;
+   default:
+   digest_nid = NID_undef;
+   }
+   }
GOST_KEY_PARAMS_free(gkp);
 
+   if (digest_nid == NID_undef) {
+   GOSTerror(GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
+   return 0;
+   }
+
ec = pkey->pkey.gost;
if (ec == NULL) {
ec = GOST_KEY_new();
@@ -137,7 +161,21 @@ encode_gost01_algor_params(const EVP_PKEY *key)
pkey_param_nid =
EC_GROUP_get_curve_name(GOST_KEY_get0_group(key->pkey.gost));
gkp->key_params = OBJ_nid2obj(pkey_param_nid);
-   gkp->hash_params = OBJ_nid2obj(GOST_KEY_get_digest(key->pkey.gost));
+   switch (pkey_param_nid) {
+   case NID_id_GostR3410_2001_TestParamSet:
+   case NID_id_GostR3410_2001_CryptoPro_A_ParamSet:
+   case NID_id_GostR3410_2001_CryptoPro_B_ParamSet:
+   case NID_id_GostR3410_2001_CryptoPro_C_ParamSet:
+   case NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet:
+   case NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet:
+   case NID_id_tc26_gost_3410_12_512_paramSetA:
+   case NID_id_tc26_gost_3410_12_512_paramSetB:
+   gkp->hash_params = 
OBJ_nid2obj(GOST_KEY_get_digest(key->pkey.gost));
+   break;
+   default:
+   gkp->hash_params = NULL;
+   break;
+   }
/*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); */
params->length = i2d_GOST_KEY_PARAMS(gkp, >data);
if (params->length <= 0) {
-- 
2.27.0



[PATCH 4/5] gostr341001: support unwrapped private keys support

2020-06-27 Thread Dmitry Baryshkov
GOST private keys can be wrapped in OCTET STRING, INTEGER or come
unwrapped. Support the latter format.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gost_asn1.c |  52 ++
 src/lib/libcrypto/gost/gost_asn1.h |  11 ++
 src/lib/libcrypto/gost/gostr341001_ameth.c | 115 +++--
 3 files changed, 169 insertions(+), 9 deletions(-)

diff --git a/src/lib/libcrypto/gost/gost_asn1.c 
b/src/lib/libcrypto/gost/gost_asn1.c
index 703d64070449..bfd81faa1ee2 100644
--- a/src/lib/libcrypto/gost/gost_asn1.c
+++ b/src/lib/libcrypto/gost/gost_asn1.c
@@ -17,6 +17,58 @@
 #include "gost_locl.h"
 #include "gost_asn1.h"
 
+static const ASN1_TEMPLATE MASKED_GOST_KEY_seq_tt[] = {
+   {
+   .flags = 0,
+   .tag = 0,
+   .offset = offsetof(MASKED_GOST_KEY, masked_priv_key),
+   .field_name = "masked_priv_key",
+   .item = _OCTET_STRING_it,
+   },
+   {
+   .flags = 0,
+   .tag = 0,
+   .offset = offsetof(MASKED_GOST_KEY, public_key),
+   .field_name = "public_key",
+   .item = _OCTET_STRING_it,
+   },
+};
+
+const ASN1_ITEM MASKED_GOST_KEY_it = {
+   .itype = ASN1_ITYPE_NDEF_SEQUENCE,
+   .utype = V_ASN1_SEQUENCE,
+   .templates = MASKED_GOST_KEY_seq_tt,
+   .tcount = sizeof(MASKED_GOST_KEY_seq_tt) / sizeof(ASN1_TEMPLATE),
+   .funcs = NULL,
+   .size = sizeof(MASKED_GOST_KEY),
+   .sname = "MASKED_GOST_KEY",
+};
+
+MASKED_GOST_KEY *
+d2i_MASKED_GOST_KEY(MASKED_GOST_KEY **a, const unsigned char **in, long len)
+{
+   return (MASKED_GOST_KEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+   _GOST_KEY_it);
+}
+
+int
+i2d_MASKED_GOST_KEY(MASKED_GOST_KEY *a, unsigned char **out)
+{
+   return ASN1_item_i2d((ASN1_VALUE *)a, out, _GOST_KEY_it);
+}
+
+MASKED_GOST_KEY *
+MASKED_GOST_KEY_new(void)
+{
+   return (MASKED_GOST_KEY *)ASN1_item_new(_GOST_KEY_it);
+}
+
+void
+MASKED_GOST_KEY_free(MASKED_GOST_KEY *a)
+{
+   ASN1_item_free((ASN1_VALUE *)a, _GOST_KEY_it);
+}
+
 static const ASN1_TEMPLATE GOST_KEY_TRANSPORT_seq_tt[] = {
{
.flags = 0,
diff --git a/src/lib/libcrypto/gost/gost_asn1.h 
b/src/lib/libcrypto/gost/gost_asn1.h
index 7cabfc79c965..cdbda7b98b67 100644
--- a/src/lib/libcrypto/gost/gost_asn1.h
+++ b/src/lib/libcrypto/gost/gost_asn1.h
@@ -56,6 +56,17 @@
 
 __BEGIN_HIDDEN_DECLS
 
+typedef struct {
+   ASN1_OCTET_STRING *masked_priv_key;
+   ASN1_OCTET_STRING *public_key;
+} MASKED_GOST_KEY;
+
+MASKED_GOST_KEY *MASKED_GOST_KEY_new(void);
+void MASKED_GOST_KEY_free(MASKED_GOST_KEY *a);
+MASKED_GOST_KEY *d2i_MASKED_GOST_KEY(MASKED_GOST_KEY **a, const unsigned char 
**in, long len);
+int i2d_MASKED_GOST_KEY(MASKED_GOST_KEY *a, unsigned char **out);
+extern const ASN1_ITEM MASKED_GOST_KEY_it;
+
 typedef struct {
ASN1_OCTET_STRING *encrypted_key;
ASN1_OCTET_STRING *imit;
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c 
b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 7cb70ed420ae..880c17ceaab8 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -437,6 +437,70 @@ priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int 
indent, ASN1_PCTX *pctx)
return pub_print_gost01(out, pkey, indent, pctx);
 }
 
+static BIGNUM *unmask_priv_key(EVP_PKEY *pk,
+   const unsigned char *buf, int len, int num_masks)
+{
+   BIGNUM *pknum_masked = NULL, *q, *mask;
+   const GOST_KEY *key_ptr = pk->pkey.gost;
+   const EC_GROUP *group = GOST_KEY_get0_group(key_ptr);
+   const unsigned char *p = buf + num_masks * len;
+   BN_CTX *ctx;
+
+   pknum_masked = GOST_le2bn(buf, len, NULL);
+   if (!pknum_masked) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   return NULL;
+   }
+
+   if (num_masks == 0)
+   return pknum_masked;
+
+   ctx = BN_CTX_new();
+   if (ctx == NULL) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   goto err;
+   }
+
+   BN_CTX_start(ctx);
+
+   q = BN_CTX_get(ctx);
+   if (!q) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   goto err;
+   }
+
+   mask = BN_CTX_get(ctx);
+   if (!mask) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   goto err;
+   }
+
+   if (EC_GROUP_get_order(group, q, NULL) <= 0) {
+   GOSTerror(ERR_R_EC_LIB);
+   goto err;
+   }
+
+   for (; p != buf; p -= len) {
+   if (GOST_le2bn(p, len, mask) == NULL ||
+   !BN_mod_mul(pknum_masked, pknum_masked, mask, q, ctx)) {
+   GOSTerror(ERR_R_BN_LIB);
+   goto err;
+   }
+   }
+
+   BN_CTX_end(ctx);
+   BN_CTX_free(ctx);
+
+   return pknum_masked;

[PATCH 2/5] gost: use ECerror to report EC errors

2020-06-27 Thread Dmitry Baryshkov
GOST code uses GOSTerror(EC_R_foo) to report several errors. Use
ECerror(EC_R_foo) instead to make error messages match error code.

Sponsored by ROSA Linux.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gostr341001_ameth.c |  2 +-
 src/lib/libcrypto/gost/gostr341001_key.c   | 14 +++---
 src/lib/libcrypto/gost/gostr341001_pmeth.c |  2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c 
b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 27a95f2069cd..0e9521178da5 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -547,7 +547,7 @@ param_decode_gost01(EVP_PKEY *pkey, const unsigned char 
**pder, int derlen)
}
group = EC_GROUP_new_by_curve_name(nid);
if (group == NULL) {
-   GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+   ECerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
GOST_KEY_free(ec);
return 0;
}
diff --git a/src/lib/libcrypto/gost/gostr341001_key.c 
b/src/lib/libcrypto/gost/gostr341001_key.c
index 0af39f21bf33..74f8cab9d86c 100644
--- a/src/lib/libcrypto/gost/gostr341001_key.c
+++ b/src/lib/libcrypto/gost/gostr341001_key.c
@@ -121,7 +121,7 @@ GOST_KEY_check_key(const GOST_KEY *key)
return 0;
}
if (EC_POINT_is_at_infinity(key->group, key->pub_key) != 0) {
-   GOSTerror(EC_R_POINT_AT_INFINITY);
+   ECerror(EC_R_POINT_AT_INFINITY);
goto err;
}
if ((ctx = BN_CTX_new()) == NULL)
@@ -131,14 +131,14 @@ GOST_KEY_check_key(const GOST_KEY *key)
 
/* testing whether the pub_key is on the elliptic curve */
if (EC_POINT_is_on_curve(key->group, key->pub_key, ctx) == 0) {
-   GOSTerror(EC_R_POINT_IS_NOT_ON_CURVE);
+   ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
/* testing whether pub_key * order is the point at infinity */
if ((order = BN_new()) == NULL)
goto err;
if (EC_GROUP_get_order(key->group, order, ctx) == 0) {
-   GOSTerror(EC_R_INVALID_GROUP_ORDER);
+   ECerror(EC_R_INVALID_GROUP_ORDER);
goto err;
}
if (EC_POINT_mul(key->group, point, NULL, key->pub_key, order,
@@ -147,7 +147,7 @@ GOST_KEY_check_key(const GOST_KEY *key)
goto err;
}
if (EC_POINT_is_at_infinity(key->group, point) == 0) {
-   GOSTerror(EC_R_WRONG_ORDER);
+   ECerror(EC_R_WRONG_ORDER);
goto err;
}
/*
@@ -156,7 +156,7 @@ GOST_KEY_check_key(const GOST_KEY *key)
 */
if (key->priv_key != NULL) {
if (BN_cmp(key->priv_key, order) >= 0) {
-   GOSTerror(EC_R_WRONG_ORDER);
+   ECerror(EC_R_WRONG_ORDER);
goto err;
}
if (EC_POINT_mul(key->group, point, key->priv_key, NULL, NULL,
@@ -165,7 +165,7 @@ GOST_KEY_check_key(const GOST_KEY *key)
goto err;
}
if (EC_POINT_cmp(key->group, point, key->pub_key, ctx) != 0) {
-   GOSTerror(EC_R_INVALID_PRIVATE_KEY);
+   ECerror(EC_R_INVALID_PRIVATE_KEY);
goto err;
}
}
@@ -212,7 +212,7 @@ GOST_KEY_set_public_key_affine_coordinates(GOST_KEY *key, 
BIGNUM *x, BIGNUM *y)
 * out of range.
 */
if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) {
-   GOSTerror(EC_R_COORDINATES_OUT_OF_RANGE);
+   ECerror(EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
if (GOST_KEY_set_public_key(key, point) == 0)
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c 
b/src/lib/libcrypto/gost/gostr341001_pmeth.c
index 0eb1d873deaf..0e0cae99e3fc 100644
--- a/src/lib/libcrypto/gost/gostr341001_pmeth.c
+++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c
@@ -246,7 +246,7 @@ pkey_gost01_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, 
size_t *siglen,
*siglen = 2 * size;
return 1;
} else if (*siglen < 2 * size) {
-   GOSTerror(EC_R_BUFFER_TOO_SMALL);
+   ECerror(EC_R_BUFFER_TOO_SMALL);
return 0;
}
if (tbs_len != 32 && tbs_len != 64) {
-- 
2.27.0



[PATCH 1/5] gost: populate params tables with new curves

2020-06-27 Thread Dmitry Baryshkov
Allow users to specify new curves via strings.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gostr341001_params.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/src/lib/libcrypto/gost/gostr341001_params.c 
b/src/lib/libcrypto/gost/gostr341001_params.c
index 282a21041999..9764964cdc1e 100644
--- a/src/lib/libcrypto/gost/gostr341001_params.c
+++ b/src/lib/libcrypto/gost/gostr341001_params.c
@@ -94,12 +94,22 @@ static const GostR3410_params GostR3410_256_params[] = {
{ "0",  NID_id_GostR3410_2001_TestParamSet },
{ "XA", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
{ "XB", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
+   { "TCA", NID_id_tc26_gost_3410_12_256_paramSetA },
+   { "TCB", NID_id_tc26_gost_3410_12_256_paramSetB },
+   { "TCC", NID_id_tc26_gost_3410_12_256_paramSetC },
+   { "TCD", NID_id_tc26_gost_3410_12_256_paramSetD },
{ NULL, NID_undef },
 };
 
 static const GostR3410_params GostR3410_512_params[] = {
{ "A",  NID_id_tc26_gost_3410_12_512_paramSetA },
{ "B",  NID_id_tc26_gost_3410_12_512_paramSetB },
+   { "C",  NID_id_tc26_gost_3410_12_512_paramSetC },
+   { "0",  NID_id_tc26_gost_3410_12_512_paramSetTest},
+   /* Duplicates for compatibility with OpenSSL */
+   { "TCA", NID_id_tc26_gost_3410_12_512_paramSetA },
+   { "TCB", NID_id_tc26_gost_3410_12_512_paramSetB },
+   { "TCC", NID_id_tc26_gost_3410_12_512_paramSetC },
{ NULL, NID_undef },
 };
 
-- 
2.27.0



[PATCH] regress/evp: add simple test for AEAD ciphers

2020-05-07 Thread Dmitry Baryshkov
Add a companion to evptest.c and aeadtest.c: test for AEAD ciphers using
EVP_CIPHER interface. For now it is capable of testing only GCM mode.

Signed-off-by: Dmitry Baryshkov 
---
 src/regress/lib/libcrypto/evp/evpaeadtest.c   | 382 ++
 .../lib/libcrypto/evp/evpaeadtests.txt|  14 +
 2 files changed, 396 insertions(+)
 create mode 100644 src/regress/lib/libcrypto/evp/evpaeadtest.c
 create mode 100644 src/regress/lib/libcrypto/evp/evpaeadtests.txt

diff --git a/src/regress/lib/libcrypto/evp/evpaeadtest.c 
b/src/regress/lib/libcrypto/evp/evpaeadtest.c
new file mode 100644
index ..6d3970ee3368
--- /dev/null
+++ b/src/regress/lib/libcrypto/evp/evpaeadtest.c
@@ -0,0 +1,382 @@
+/* $OpenBSD: evptest.c,v 1.9 2020/01/26 02:46:26 tb Exp $  */
+/* Written by Ben Laurie, 2001 */
+/*
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in
+ *the documentation and/or other materials provided with the
+ *distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *software must display the following acknowledgment:
+ *"This product includes software developed by the OpenSSL Project
+ *for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *endorse or promote products derived from this software without
+ *prior written permission. For written permission, please contact
+ *openssl-c...@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *nor may "OpenSSL" appear in their names without prior written
+ *permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *acknowledgment:
+ *"This product includes software developed by the OpenSSL Project
+ *for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+#include 
+#include 
+
+static void
+hexdump(FILE *f, const char *title, const unsigned char *s, int l)
+{
+   int n = 0;
+
+   fprintf(f, "%s",title);
+   for (; n < l; ++n) {
+   if ((n % 16) == 0)
+   fprintf(f, "\n%04x",n);
+   fprintf(f, " %02x",s[n]);
+   }
+   fprintf(f, "\n");
+}
+
+static int
+convert(unsigned char *s)
+{
+   unsigned char *d;
+
+   for (d = s; *s; s += 2,++d) {
+   unsigned int n;
+
+   if (!s[1]) {
+   fprintf(stderr, "Odd number of hex digits!\n");
+   exit(4);
+   }
+   if (sscanf((char *)s, "%2x", ) != 1) {
+   fprintf(stderr, "Invalid hex value at %s\n", s);
+   exit(4);
+   }
+
+   *d = (unsigned char)n;
+   }
+   return s - d;
+}
+
+static char *
+sstrsep(char **string, const char *delim)
+{
+   char isdelim[256];
+   char *token = *string;
+
+   if (**string == 0)
+   return NULL;
+
+   memset(isdelim, 0, 256);
+   isdelim[0] = 1;
+
+   while (*delim) {
+   isdelim[(unsigned char)(*delim)] = 1;
+   delim++;
+   }
+
+   while (!isdelim[(unsigned char)(**string)]) {
+   (*string)++;
+   }
+
+   if (**string) {
+   **string = 0;
+   (*string)++;
+   }
+
+   return token;
+}
+
+static unsigned char *
+ustrsep(char **p, const char *sep)
+{
+   return (unsigned char *)sstrsep(p, sep);
+}
+

[PATCH 0/5] gost: add support for magma and kuznyechik ciphers

2020-04-07 Thread Dmitry Baryshkov
Russian standards body has issues a standard GOST R 34.12-2015 defining
two block ciphers: magma and kuznyechik. English descriptions of these
ciphers are defined in draft-dolmatov-magma (in RFC editor queue) and
RFC 7801 respectively. These patches add support for basic constructions
using these ciphers.




[PATCH 1/5] modes: add functions implementing common code for 64-bit ciphers

2020-04-07 Thread Dmitry Baryshkov
64-bit ciphers are old, but it would be good to use common code for
their implementations.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/modes/cbc64.c | 202 
 src/lib/libcrypto/modes/cfb64.c | 169 ++
 src/lib/libcrypto/modes/ctr64.c | 174 +++
 src/lib/libcrypto/modes/modes.h |  26 
 src/lib/libcrypto/modes/ofb64.c | 119 +++
 5 files changed, 690 insertions(+)
 create mode 100644 src/lib/libcrypto/modes/cbc64.c
 create mode 100644 src/lib/libcrypto/modes/cfb64.c
 create mode 100644 src/lib/libcrypto/modes/ctr64.c
 create mode 100644 src/lib/libcrypto/modes/ofb64.c

diff --git a/src/lib/libcrypto/modes/cbc64.c b/src/lib/libcrypto/modes/cbc64.c
new file mode 100644
index ..ec65ac5d3468
--- /dev/null
+++ b/src/lib/libcrypto/modes/cbc64.c
@@ -0,0 +1,202 @@
+/* $OpenBSD: cbc64.c,v 1.4 2015/02/10 09:46:30 miod Exp $ */
+/* 
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in
+ *the documentation and/or other materials provided with the
+ *distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *software must display the following acknowledgment:
+ *"This product includes software developed by the OpenSSL Project
+ *for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *endorse or promote products derived from this software without
+ *prior written permission. For written permission, please contact
+ *openssl-c...@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *nor may "OpenSSL" appear in their names without prior written
+ *permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *acknowledgment:
+ *"This product includes software developed by the OpenSSL Project
+ *for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ *
+ */
+
+#include 
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+#undef STRICT_ALIGNMENT
+#ifdef __STRICT_ALIGNMENT
+#define STRICT_ALIGNMENT 1
+#else
+#define STRICT_ALIGNMENT 0
+#endif
+
+void CRYPTO_cbc64_encrypt(const unsigned char *in, unsigned char *out,
+   size_t len, const void *key,
+   unsigned char ivec[8], block64_f block)
+{
+   size_t n;
+   const unsigned char *iv = ivec;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+   if (STRICT_ALIGNMENT &&
+   ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+   while (len>=8) {
+   for(n=0; n<8; ++n)
+   out[n] = in[n] ^ iv[n];
+   (*block)(out, out, key);
+   iv = out;
+   len -= 8;
+   in  += 8;
+   out += 8;
+   }
+   } else {
+   while (len>=8) {
+   for(n=0; n<8; n+=sizeof(size_t))
+   *(size_t*)(out+n) =
+   *(size_t*)(in+n) ^ *(size_t*)(iv+n);
+   (*block)(out, out, key);
+   iv = out;
+   len -= 8;
+   in  += 8;
+   out += 8;
+   }
+   }
+#endif
+   while (len) {
+ 

[PATCH 3/5] gost: use key_meshing for specifying section size

2020-04-07 Thread Dmitry Baryshkov
In preparation to adding ACPKM support, switch key_meshing to be a
section size rather than just a flag.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gost.h  | 2 +-
 src/lib/libcrypto/gost/gost2814789.c   | 8 
 src/lib/libcrypto/gost/gost89_params.c | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index b6e5b51c40d4..a9ed5a1c50df 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -69,7 +69,7 @@ typedef struct gost2814789_key_st {
unsigned int key[8];
unsigned int k87[256],k65[256],k43[256],k21[256];
unsigned int count;
-   unsigned key_meshing : 1;
+   unsigned int key_meshing;
 } GOST2814789_KEY;
 
 int Gost2814789_set_sbox(GOST2814789_KEY *key, int nid);
diff --git a/src/lib/libcrypto/gost/gost2814789.c 
b/src/lib/libcrypto/gost/gost2814789.c
index 5016ed004b32..e5c7f6a2b3dd 100644
--- a/src/lib/libcrypto/gost/gost2814789.c
+++ b/src/lib/libcrypto/gost/gost2814789.c
@@ -169,7 +169,7 @@ void
 Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out,
 GOST2814789_KEY *key, const int enc)
 {
-   if (key->key_meshing && key->count == 1024) {
+   if (key->key_meshing && key->count == key->key_meshing) {
Gost2814789_cryptopro_key_mesh(key);
key->count = 0;
}
@@ -183,7 +183,7 @@ Gost2814789_ecb_encrypt(const unsigned char *in, unsigned 
char *out,
 static inline void
 Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *key)
 {
-   if (key->key_meshing && key->count == 1024) {
+   if (key->key_meshing && key->count == key->key_meshing) {
Gost2814789_cryptopro_key_mesh(key);
Gost2814789_encrypt(iv, iv, key);
key->count = 0;
@@ -196,7 +196,7 @@ static inline void
 Gost2814789_mac_mesh(const unsigned char *data, unsigned char *mac,
 GOST2814789_KEY *key)
 {
-   if (key->key_meshing && key->count == 1024) {
+   if (key->key_meshing && key->count == key->key_meshing) {
Gost2814789_cryptopro_key_mesh(key);
key->count = 0;
}
@@ -328,7 +328,7 @@ Gost2814789_cnt_next(unsigned char *ivec, unsigned char 
*out,
if (key->count == 0)
Gost2814789_encrypt(ivec, ivec, key);
 
-   if (key->key_meshing && key->count == 1024) {
+   if (key->key_meshing && key->count == key->key_meshing) {
Gost2814789_cryptopro_key_mesh(key);
Gost2814789_encrypt(ivec, ivec, key);
key->count = 0;
diff --git a/src/lib/libcrypto/gost/gost89_params.c 
b/src/lib/libcrypto/gost/gost89_params.c
index 526710cb043f..c454fd7afc40 100644
--- a/src/lib/libcrypto/gost/gost89_params.c
+++ b/src/lib/libcrypto/gost/gost89_params.c
@@ -191,7 +191,7 @@ Gost2814789_set_sbox(GOST2814789_KEY *key, int nid)
continue;
 
b = gost_cipher_list[i].sblock;
-   key->key_meshing = gost_cipher_list[i].key_meshing;
+   key->key_meshing = gost_cipher_list[i].key_meshing ? 1024 : 0;
break;
}
 
-- 
2.25.1



[PATCH 2/5] gost: drop key_len from Gost28147_set_key

2020-04-07 Thread Dmitry Baryshkov
There is no point in specifying key length to Gost28147_set_key,
everybody just passes 256 (or 32 * 8) no matter what.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/evp/e_gost2814789.c   |  4 +++-
 src/lib/libcrypto/evp/m_gost2814789.c   |  3 ++-
 src/lib/libcrypto/gost/gost.h   |  3 +--
 src/lib/libcrypto/gost/gost2814789.c|  2 +-
 src/lib/libcrypto/gost/gost89_keywrap.c |  6 +++---
 src/lib/libcrypto/gost/gost89_params.c  | 12 +++-
 src/lib/libcrypto/gost/gostr341194.c|  8 
 7 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/src/lib/libcrypto/evp/e_gost2814789.c 
b/src/lib/libcrypto/evp/e_gost2814789.c
index 730de4fed1d9..e3c608f0eb4f 100644
--- a/src/lib/libcrypto/evp/e_gost2814789.c
+++ b/src/lib/libcrypto/evp/e_gost2814789.c
@@ -93,7 +93,9 @@ gost2814789_init_key(EVP_CIPHER_CTX *ctx, const unsigned char 
*key,
 {
EVP_GOST2814789_CTX *c = ctx->cipher_data;
 
-   return Gost2814789_set_key(>ks, key, ctx->key_len * 8);
+   Gost2814789_set_key(>ks, key);
+
+   return 1;
 }
 
 int
diff --git a/src/lib/libcrypto/evp/m_gost2814789.c 
b/src/lib/libcrypto/evp/m_gost2814789.c
index 279af872e022..779ccf07df14 100644
--- a/src/lib/libcrypto/evp/m_gost2814789.c
+++ b/src/lib/libcrypto/evp/m_gost2814789.c
@@ -82,7 +82,8 @@ gost2814789_md_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void 
*p2)
 
switch (cmd) {
case EVP_MD_CTRL_SET_KEY:
-   return Gost2814789_set_key(>cipher, p2, p1);
+   Gost2814789_set_key(>cipher, p2);
+   return 1;
case EVP_MD_CTRL_GOST_SET_SBOX:
return Gost2814789_set_sbox(>cipher, p1);
}
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index 092f96fb60ce..b6e5b51c40d4 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -73,8 +73,7 @@ typedef struct gost2814789_key_st {
 } GOST2814789_KEY;
 
 int Gost2814789_set_sbox(GOST2814789_KEY *key, int nid);
-int Gost2814789_set_key(GOST2814789_KEY *key,
-   const unsigned char *userKey, const int bits);
+void Gost2814789_set_key(GOST2814789_KEY *key, const unsigned char *userKey);
 void Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out,
GOST2814789_KEY *key, const int enc);
 void Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out,
diff --git a/src/lib/libcrypto/gost/gost2814789.c 
b/src/lib/libcrypto/gost/gost2814789.c
index e285413ed460..5016ed004b32 100644
--- a/src/lib/libcrypto/gost/gost2814789.c
+++ b/src/lib/libcrypto/gost/gost2814789.c
@@ -461,7 +461,7 @@ GOST2814789IMIT(const unsigned char *d, size_t n, unsigned 
char *md, int nid,
md = m;
GOST2814789IMIT_Init(, nid);
memcpy(c.mac, iv, 8);
-   Gost2814789_set_key(, key, 256);
+   Gost2814789_set_key(, key);
GOST2814789IMIT_Update(, d, n);
GOST2814789IMIT_Final(md, );
explicit_bzero(, sizeof(c));
diff --git a/src/lib/libcrypto/gost/gost89_keywrap.c 
b/src/lib/libcrypto/gost/gost89_keywrap.c
index a754c4d56ea1..47a11ad0c44e 100644
--- a/src/lib/libcrypto/gost/gost89_keywrap.c
+++ b/src/lib/libcrypto/gost/gost89_keywrap.c
@@ -85,7 +85,7 @@ key_diversify_crypto_pro(GOST2814789_KEY *ctx, const unsigned 
char *inputKey,
p = S;
l2c (s1, p);
l2c (s2, p);
-   Gost2814789_set_key(ctx, outputKey, 256);
+   Gost2814789_set_key(ctx, outputKey);
mask = 0;
Gost2814789_cfb64_encrypt(outputKey, outputKey, 32, ctx, S,
, 1);
@@ -102,7 +102,7 @@ gost_key_wrap_crypto_pro(int nid, const unsigned char 
*keyExchangeKey,
 
Gost2814789_set_sbox(, nid);
key_diversify_crypto_pro(, keyExchangeKey, ukm, kek_ukm);
-   Gost2814789_set_key(, kek_ukm, 256);
+   Gost2814789_set_key(, kek_ukm);
memcpy(wrappedKey, ukm, 8);
Gost2814789_encrypt(sessionKey +  0, wrappedKey + 8 +  0, );
Gost2814789_encrypt(sessionKey +  8, wrappedKey + 8 +  8, );
@@ -122,7 +122,7 @@ gost_key_unwrap_crypto_pro(int nid, const unsigned char 
*keyExchangeKey,
Gost2814789_set_sbox(, nid);
/* First 8 bytes of wrapped Key is ukm */
key_diversify_crypto_pro(, keyExchangeKey, wrappedKey, kek_ukm);
-   Gost2814789_set_key(, kek_ukm, 256);
+   Gost2814789_set_key(, kek_ukm);
Gost2814789_decrypt(wrappedKey + 8 +  0, sessionKey +  0, );
Gost2814789_decrypt(wrappedKey + 8 +  8, sessionKey +  8, );
Gost2814789_decrypt(wrappedKey + 8 + 16, sessionKey + 16, );
diff --git a/src/lib/libcrypto/gost/gost89_params.c 
b/src/lib/libcrypto/gost/gost89_params.c
index 35d8f62fe960..526710cb043f 100644
--- a/src/lib/libcrypto/gost/gost89_params.c
+++ b/src/lib/libcrypto/gost/gost89_params.c
@@ -212,21 +212,15 @@ Gost2814789_set_sbox(GOST2814789_KEY *key, int nid)
return 1;
 }
 
-int
-Gost2814789_se

[PATCH 4/5] gost: add support for magma cipher

2020-04-07 Thread Dmitry Baryshkov
GOST R 34.12-2015 defines Magma cipher (a variant of GOST 28147-89 with
fixed S-BOX and endianness change), see draft-dolmatov-magma.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/Symbols.list |   5 +
 src/lib/libcrypto/evp/c_all.c  |   5 +
 src/lib/libcrypto/evp/e_magma.c| 123 +
 src/lib/libcrypto/evp/evp.h|   5 +
 src/lib/libcrypto/gost/gost.h  |  29 +
 src/lib/libcrypto/gost/gost2814789.c   |  71 
 src/lib/libcrypto/gost/gost89_params.c |  24 
 src/lib/libcrypto/gost/gost_locl.h |  12 ++
 src/lib/libcrypto/objects/obj_mac.num  |   9 ++
 src/lib/libcrypto/objects/objects.txt  |  14 +++
 src/regress/lib/libcrypto/evp/evptests.txt |  18 +++
 11 files changed, 315 insertions(+)
 create mode 100644 src/lib/libcrypto/evp/e_magma.c

diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index 662eb4dc291e..6102af2f8b24 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1725,6 +1725,11 @@ EVP_idea_cfb
 EVP_idea_cfb64
 EVP_idea_ecb
 EVP_idea_ofb
+EVP_magma_cbc
+EVP_magma_cfb64
+EVP_magma_ctr
+EVP_magma_ecb
+EVP_magma_ofb
 EVP_md4
 EVP_md5
 EVP_md5_sha1
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index 9e9d39d5abaa..59342beb7a00 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -229,6 +229,11 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_gost2814789_ecb());
EVP_add_cipher(EVP_gost2814789_cfb64());
EVP_add_cipher(EVP_gost2814789_cnt());
+   EVP_add_cipher(EVP_magma_ecb());
+   EVP_add_cipher(EVP_magma_cbc());
+   EVP_add_cipher(EVP_magma_cfb64());
+   EVP_add_cipher(EVP_magma_ofb());
+   EVP_add_cipher(EVP_magma_ctr());
 #endif
 
 #ifndef OPENSSL_NO_SM4
diff --git a/src/lib/libcrypto/evp/e_magma.c b/src/lib/libcrypto/evp/e_magma.c
new file mode 100644
index ..90130808a00a
--- /dev/null
+++ b/src/lib/libcrypto/evp/e_magma.c
@@ -0,0 +1,123 @@
+/* $OpenBSD: e_magma.c,v 1.4 2017/01/29 17:49:23 beck Exp $ */
+/*
+ * Copyright (c) 2020 Dmitry Baryshkov 
+ *
+ * Sponsored by ROSA Linux
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+#include 
+#include "evp_locl.h"
+
+typedef struct {
+   MAGMA_KEY ks;
+} EVP_MAGMA_CTX;
+
+static int
+magma_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+const unsigned char *iv, int enc)
+{
+   EVP_MAGMA_CTX *c = ctx->cipher_data;
+
+   Magma_set_key(>ks, key);
+
+   return 1;
+}
+
+static int
+magma_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+   switch (type) {
+   case EVP_CTRL_PBE_PRF_NID:
+   if (ptr != NULL) {
+   *((int *)ptr) = NID_id_tc26_hmac_gost_3411_12_256;
+   return 1;
+   } else {
+   return 0;
+   }
+   default:
+   return -1;
+   }
+}
+
+static void
+Magma_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
+   const MAGMA_KEY *key, unsigned char *ivec, const int enc)
+{
+   if (enc)
+   CRYPTO_cbc64_encrypt(in, out, len, key, ivec,
+   (block64_f)Magma_encrypt);
+   else
+   CRYPTO_cbc64_decrypt(in, out, len, key, ivec,
+   (block64_f)Magma_decrypt);
+}
+
+static void
+Magma_cfb64_encrypt(const unsigned char *in, unsigned char *out, size_t length,
+   const MAGMA_KEY *key, unsigned char *ivec, int *num, const int 
enc)
+{
+   CRYPTO_cfb64_encrypt(in, out, length, key, ivec, num, enc,
+   (block64_f)Magma_encrypt);
+}
+
+static void
+Magma_ecb_encrypt(const unsigned char *in, unsigned char *out, const MAGMA_KEY 
*key,
+   const int enc)
+{
+   if (enc)
+   Magma_encrypt(in, out, key);
+   else
+   Magma_decrypt(in, out, key);
+}
+
+static void
+Magma_ofb64_encrypt(const unsigned char *in, unsigned char *out, size_t length,
+   const MAGMA_KEY *key, uns

[PATCH 3/3] pkcs12: add support for GOST PFX files

2020-04-07 Thread Dmitry Baryshkov
Russian standard body has changed the way MAC key is calculated for
PKCS12 files. Generate proper keys depending on the digest type used for
MAC generation.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/pkcs12/p12_key.c  | 18 ++
 src/lib/libcrypto/pkcs12/p12_mutl.c | 28 +---
 src/lib/libcrypto/pkcs12/pkcs12.h   |  5 +
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/src/lib/libcrypto/pkcs12/p12_key.c 
b/src/lib/libcrypto/pkcs12/p12_key.c
index d419a9d83598..9a5297a23131 100644
--- a/src/lib/libcrypto/pkcs12/p12_key.c
+++ b/src/lib/libcrypto/pkcs12/p12_key.c
@@ -195,3 +195,21 @@ end:
EVP_MD_CTX_cleanup();
return ret;
 }
+
+int
+PKCS12_key_gen_gost(const char *pass, int passlen, unsigned char *salt,
+int saltlen, int iter, int n, unsigned char *out,
+const EVP_MD *md_type)
+{
+   unsigned char buf[96];
+
+   if (n != PKCS12_GOST_KEY_LEN)
+   return 0;
+
+   if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, md_type, 
sizeof(buf), buf))
+   return 0;
+
+   memcpy(out, buf + sizeof(buf) - PKCS12_GOST_KEY_LEN, 
PKCS12_GOST_KEY_LEN);
+
+   return 1;
+}
diff --git a/src/lib/libcrypto/pkcs12/p12_mutl.c 
b/src/lib/libcrypto/pkcs12/p12_mutl.c
index f3132ec75f68..023bbbd92db1 100644
--- a/src/lib/libcrypto/pkcs12/p12_mutl.c
+++ b/src/lib/libcrypto/pkcs12/p12_mutl.c
@@ -74,6 +74,7 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
 unsigned char *mac, unsigned int *maclen)
 {
const EVP_MD *md_type;
+   int md_type_nid;
HMAC_CTX hmac;
unsigned char key[EVP_MAX_MD_SIZE], *salt;
int saltlen, iter;
@@ -97,13 +98,26 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
PKCS12error(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
return 0;
}
-   md_size = EVP_MD_size(md_type);
-   if (md_size < 0)
-   return 0;
-   if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
-   md_size, key, md_type)) {
-   PKCS12error(PKCS12_R_KEY_GEN_ERROR);
-   return 0;
+   md_type_nid = EVP_MD_type(md_type);
+   if ((md_type_nid == NID_id_GostR3411_94 ||
+md_type_nid == NID_id_tc26_gost3411_2012_256 ||
+md_type_nid == NID_id_tc26_gost3411_2012_512) &&
+   getenv("LEGACY_GOST_PKCS12") == NULL) {
+   md_size = PKCS12_GOST_KEY_LEN;
+   if (!PKCS12_key_gen_gost(pass, passlen, salt, saltlen, iter,
+   md_size, key, md_type)) {
+   PKCS12error(PKCS12_R_KEY_GEN_ERROR);
+   return 0;
+   }
+   } else {
+   md_size = EVP_MD_size(md_type);
+   if (md_size < 0)
+   return 0;
+   if (!PKCS12_key_gen(pass, passlen, salt, saltlen, 
PKCS12_MAC_ID, iter,
+   md_size, key, md_type)) {
+   PKCS12error(PKCS12_R_KEY_GEN_ERROR);
+   return 0;
+   }
}
HMAC_CTX_init();
if (!HMAC_Init_ex(, key, md_size, md_type, NULL) ||
diff --git a/src/lib/libcrypto/pkcs12/pkcs12.h 
b/src/lib/libcrypto/pkcs12/pkcs12.h
index 56635f9d7e0a..4dab109bbc3a 100644
--- a/src/lib/libcrypto/pkcs12/pkcs12.h
+++ b/src/lib/libcrypto/pkcs12/pkcs12.h
@@ -91,6 +91,11 @@ extern "C" {
 #define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
 #endif
 
+#define PKCS12_GOST_KEY_LEN 32
+int PKCS12_key_gen_gost(const char *pass, int passlen, unsigned char *salt,
+int saltlen, int iter, int n, unsigned char *out,
+const EVP_MD *md_type);
+
 /* MS key usage constants */
 
 #define KEY_EX 0x10
-- 
2.25.1



[PATCH 1/3] Add OIDs for GOST R 34.11-2012 HMAC functions

2020-04-07 Thread Dmitry Baryshkov
Add OIDs for HMAC using Streebog (GOST R 34.11-2012) hash function.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/objects/obj_mac.num | 2 ++
 src/lib/libcrypto/objects/objects.txt | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/src/lib/libcrypto/objects/obj_mac.num 
b/src/lib/libcrypto/objects/obj_mac.num
index 3f0b5666fb51..ba75ec246eb5 100644
--- a/src/lib/libcrypto/objects/obj_mac.num
+++ b/src/lib/libcrypto/objects/obj_mac.num
@@ -996,3 +996,5 @@ id_tc26_gost_3410_12_256_paramSetC  995
 id_tc26_gost_3410_12_256_paramSetD 996
 id_tc26_gost_3410_12_512_paramSetTest  997
 id_tc26_gost_3410_12_512_paramSetC 998
+id_tc26_hmac_gost_3411_12_256  999
+id_tc26_hmac_gost_3411_12_512  1000
diff --git a/src/lib/libcrypto/objects/objects.txt 
b/src/lib/libcrypto/objects/objects.txt
index 42f31c3cbec1..8e533530f28d 100644
--- a/src/lib/libcrypto/objects/objects.txt
+++ b/src/lib/libcrypto/objects/objects.txt
@@ -1372,6 +1372,8 @@ member-body 643 7 1   : tc26
 tc26 1 2 2 : streebog256 : GOST R 34.11-2012 (256 bit)
 !Cname id-tc26-gost3411-2012-512
 tc26 1 2 3 : streebog512 : GOST R 34-11-2012 (512 bit)
+tc26 1 4 1 : id-tc26-hmac-gost-3411-12-256 : HMAC STREEBOG 256
+tc26 1 4 2 : id-tc26-hmac-gost-3411-12-512 : HMAC STREEBOG 512
 tc26 2 1 1 1   : id-tc26-gost-3410-12-256-paramSetA : GOST R 
34.10-2012 (256 bit) ParamSet A
 tc26 2 1 1 2   : id-tc26-gost-3410-12-256-paramSetB : GOST R 
34.10-2012 (256 bit) ParamSet B
 tc26 2 1 1 3   : id-tc26-gost-3410-12-256-paramSetC : GOST R 
34.10-2012 (256 bit) ParamSet C
-- 
2.25.1



[PATCH 2/3] Populate PBE table with GOST R 34.11-2012 HMAC ids

2020-04-07 Thread Dmitry Baryshkov
Allow using GOST R 34.11-2012 in PBE/PBKDF2/PKCS#5.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/evp/evp_pbe.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/lib/libcrypto/evp/evp_pbe.c b/src/lib/libcrypto/evp/evp_pbe.c
index de08c8d78c52..4305d026425a 100644
--- a/src/lib/libcrypto/evp/evp_pbe.c
+++ b/src/lib/libcrypto/evp/evp_pbe.c
@@ -114,6 +114,8 @@ static const EVP_PBE_CTL builtin_pbe[] = {
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
{EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
+   {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_12_256, -1, 
NID_id_tc26_gost3411_2012_256, 0},
+   {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_12_512, -1, 
NID_id_tc26_gost3411_2012_512, 0},
 };
 
 int
-- 
2.25.1



[PATCH v2] gostr341001: support unwrapped private keys support

2020-04-06 Thread Dmitry Baryshkov
GOST private keys can be wrapped in OCTET STRING, INTEGER or come
unwrapped. Support the latter format.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gost_asn1.c |  52 ++
 src/lib/libcrypto/gost/gost_asn1.h |  11 ++
 src/lib/libcrypto/gost/gostr341001_ameth.c | 115 +++--
 3 files changed, 169 insertions(+), 9 deletions(-)

diff --git a/src/lib/libcrypto/gost/gost_asn1.c 
b/src/lib/libcrypto/gost/gost_asn1.c
index 703d64070449..bfd81faa1ee2 100644
--- a/src/lib/libcrypto/gost/gost_asn1.c
+++ b/src/lib/libcrypto/gost/gost_asn1.c
@@ -17,6 +17,58 @@
 #include "gost_locl.h"
 #include "gost_asn1.h"
 
+static const ASN1_TEMPLATE MASKED_GOST_KEY_seq_tt[] = {
+   {
+   .flags = 0,
+   .tag = 0,
+   .offset = offsetof(MASKED_GOST_KEY, masked_priv_key),
+   .field_name = "masked_priv_key",
+   .item = _OCTET_STRING_it,
+   },
+   {
+   .flags = 0,
+   .tag = 0,
+   .offset = offsetof(MASKED_GOST_KEY, public_key),
+   .field_name = "public_key",
+   .item = _OCTET_STRING_it,
+   },
+};
+
+const ASN1_ITEM MASKED_GOST_KEY_it = {
+   .itype = ASN1_ITYPE_NDEF_SEQUENCE,
+   .utype = V_ASN1_SEQUENCE,
+   .templates = MASKED_GOST_KEY_seq_tt,
+   .tcount = sizeof(MASKED_GOST_KEY_seq_tt) / sizeof(ASN1_TEMPLATE),
+   .funcs = NULL,
+   .size = sizeof(MASKED_GOST_KEY),
+   .sname = "MASKED_GOST_KEY",
+};
+
+MASKED_GOST_KEY *
+d2i_MASKED_GOST_KEY(MASKED_GOST_KEY **a, const unsigned char **in, long len)
+{
+   return (MASKED_GOST_KEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+   _GOST_KEY_it);
+}
+
+int
+i2d_MASKED_GOST_KEY(MASKED_GOST_KEY *a, unsigned char **out)
+{
+   return ASN1_item_i2d((ASN1_VALUE *)a, out, _GOST_KEY_it);
+}
+
+MASKED_GOST_KEY *
+MASKED_GOST_KEY_new(void)
+{
+   return (MASKED_GOST_KEY *)ASN1_item_new(_GOST_KEY_it);
+}
+
+void
+MASKED_GOST_KEY_free(MASKED_GOST_KEY *a)
+{
+   ASN1_item_free((ASN1_VALUE *)a, _GOST_KEY_it);
+}
+
 static const ASN1_TEMPLATE GOST_KEY_TRANSPORT_seq_tt[] = {
{
.flags = 0,
diff --git a/src/lib/libcrypto/gost/gost_asn1.h 
b/src/lib/libcrypto/gost/gost_asn1.h
index 7cabfc79c965..cdbda7b98b67 100644
--- a/src/lib/libcrypto/gost/gost_asn1.h
+++ b/src/lib/libcrypto/gost/gost_asn1.h
@@ -56,6 +56,17 @@
 
 __BEGIN_HIDDEN_DECLS
 
+typedef struct {
+   ASN1_OCTET_STRING *masked_priv_key;
+   ASN1_OCTET_STRING *public_key;
+} MASKED_GOST_KEY;
+
+MASKED_GOST_KEY *MASKED_GOST_KEY_new(void);
+void MASKED_GOST_KEY_free(MASKED_GOST_KEY *a);
+MASKED_GOST_KEY *d2i_MASKED_GOST_KEY(MASKED_GOST_KEY **a, const unsigned char 
**in, long len);
+int i2d_MASKED_GOST_KEY(MASKED_GOST_KEY *a, unsigned char **out);
+extern const ASN1_ITEM MASKED_GOST_KEY_it;
+
 typedef struct {
ASN1_OCTET_STRING *encrypted_key;
ASN1_OCTET_STRING *imit;
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c 
b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 49eec7a31d70..da354d0fe66d 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -437,6 +437,70 @@ priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int 
indent, ASN1_PCTX *pctx)
return pub_print_gost01(out, pkey, indent, pctx);
 }
 
+static BIGNUM *unmask_priv_key(EVP_PKEY *pk,
+   const unsigned char *buf, int len, int num_masks)
+{
+   BIGNUM *pknum_masked = NULL, *q, *mask;
+   const GOST_KEY *key_ptr = pk->pkey.gost;
+   const EC_GROUP *group = GOST_KEY_get0_group(key_ptr);
+   const unsigned char *p = buf + num_masks * len;
+   BN_CTX *ctx;
+
+   pknum_masked = GOST_le2bn(buf, len, NULL);
+   if (!pknum_masked) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   return NULL;
+   }
+
+   if (num_masks == 0)
+   return pknum_masked;
+
+   ctx = BN_CTX_new();
+   if (ctx == NULL) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   goto err;
+   }
+
+   BN_CTX_start(ctx);
+
+   q = BN_CTX_get(ctx);
+   if (!q) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   goto err;
+   }
+
+   mask = BN_CTX_get(ctx);
+   if (!mask) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   goto err;
+   }
+
+   if (EC_GROUP_get_order(group, q, NULL) <= 0) {
+   GOSTerror(ERR_R_EC_LIB);
+   goto err;
+   }
+
+   for (; p != buf; p -= len) {
+   if (GOST_le2bn(p, len, mask) == NULL ||
+   !BN_mod_mul(pknum_masked, pknum_masked, mask, q, ctx)) {
+   GOSTerror(ERR_R_BN_LIB);
+   goto err;
+   }
+   }
+
+   BN_CTX_end(ctx);
+   BN_CTX_free(ctx);
+
+   return pknum_masked;

Re: [PATCH 1/2] gost: add missing error reporting

2020-04-04 Thread Dmitry Baryshkov
Hello,

сб, 28 мар. 2020 г. в 17:20, Kinichiro Inoguchi :
>
> I had checked this by portable build and all regresses passed.
> I'm ok with this diff.

Thank you! Any further actions required from my side?

> On Thu, Mar 26, 2020 at 09:28:01PM +0300, dbarysh...@gmail.com wrote:
> > From: Dmitry Baryshkov 
> >
> > Add few more error reports to help debugging.
> >
> > Sponsored by ROSA Linux.
> >
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >  src/lib/libcrypto/gost/gostr341001_ameth.c | 20 +++-
> >  1 file changed, 15 insertions(+), 5 deletions(-)

-- 
With best wishes
Dmitry



Re: [PATCH] gostr341001: support unwrapped private keys support

2020-03-31 Thread Dmitry Baryshkov
Hello,

вт, 31 мар. 2020 г. в 06:20, Kinichiro Inoguchi :
>
> Hi,
>
> Where can we see the specifcation for these 3 different format, wrapped in 
> OCTET STRING, INTEGER and unwrapped but masked ?
> I tried to find but couldn't.

There is no English specification for GOST PKCS8 files yet,
unfortunately. You can find similar pieces of code in OpenSSL's GOST
engine (https://github.com/gost-engine/engine/blob/master/gost_ameth.c#L347)
and in GnuTLS 
(https://gitlab.com/gnutls/gnutls/-/blob/master/lib/x509/privkey_pkcs8.c#L1159).

-- 
With best wishes
Dmitry



[PATCH v3 2/2] gost: populate params tables with new curves

2020-03-29 Thread Dmitry Baryshkov
Allow users to specify new curves via strings.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gostr341001_params.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/src/lib/libcrypto/gost/gostr341001_params.c 
b/src/lib/libcrypto/gost/gostr341001_params.c
index 13054cd0fc26..138860dee56e 100644
--- a/src/lib/libcrypto/gost/gostr341001_params.c
+++ b/src/lib/libcrypto/gost/gostr341001_params.c
@@ -94,12 +94,22 @@ static const GostR3410_params GostR3410_256_params[] = {
{ "0",  NID_id_GostR3410_2001_TestParamSet },
{ "XA", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
{ "XB", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
+   { "TCA", NID_id_tc26_gost_3410_12_256_paramSetA },
+   { "TCB", NID_id_tc26_gost_3410_12_256_paramSetB },
+   { "TCC", NID_id_tc26_gost_3410_12_256_paramSetC },
+   { "TCD", NID_id_tc26_gost_3410_12_256_paramSetD },
{ NULL, NID_undef },
 };
 
 static const GostR3410_params GostR3410_512_params[] = {
{ "A",  NID_id_tc26_gost_3410_12_512_paramSetA },
{ "B",  NID_id_tc26_gost_3410_12_512_paramSetB },
+   { "C",  NID_id_tc26_gost_3410_12_512_paramSetC },
+   { "0",  NID_id_tc26_gost_3410_12_512_paramSetTest},
+   /* Duplicates for compatibility with OpenSSL */
+   { "TCA", NID_id_tc26_gost_3410_12_512_paramSetA },
+   { "TCB", NID_id_tc26_gost_3410_12_512_paramSetB },
+   { "TCC", NID_id_tc26_gost_3410_12_512_paramSetC },
{ NULL, NID_undef },
 };
 
-- 
2.25.1



Re: [PATCH v2 2/2] gost: populate params tables with new curves

2020-03-29 Thread Dmitry Baryshkov
Hello,

вс, 29 мар. 2020 г. в 06:03, Kinichiro Inoguchi :
>
> Hi,
> I have 2 questions.
>
> In GostR3410_512_params[], "A" and "TCA" have the same NID, "B" and "TCB" too.
> I thought these were redundant, but are there any reasons for this ?

Compatibility with OpenSSL's gost engine, which uses TCA/TCB/TCC here.

> In GostR3410_512_params[], don't you need the record for
> NID_id_tc26_gost_3410_12_512_paramSetTest ?

This param set is used for testing/example certificates. It should not
be used in production.
I will add in in V3 though.

> Best regards,
>
>
> On Sat, Mar 28, 2020 at 07:16:14PM +0300, Dmitry Baryshkov wrote:
> > Allow users to specify new curves via strings.
> >
> > Sponsored by ROSA Linux
> >
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >  src/lib/libcrypto/gost/gostr341001_params.c | 7 +++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git a/src/lib/libcrypto/gost/gostr341001_params.c 
> > b/src/lib/libcrypto/gost/gostr341001_params.c
> > index 13054cd0fc26..0f068d97eb0a 100644
> > --- a/src/lib/libcrypto/gost/gostr341001_params.c
> > +++ b/src/lib/libcrypto/gost/gostr341001_params.c
> > @@ -94,12 +94,19 @@ static const GostR3410_params GostR3410_256_params[] = {
> >   { "0",  NID_id_GostR3410_2001_TestParamSet },
> >   { "XA", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
> >   { "XB", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
> > + { "TCA", NID_id_tc26_gost_3410_12_256_paramSetA },
> > + { "TCB", NID_id_tc26_gost_3410_12_256_paramSetB },
> > + { "TCC", NID_id_tc26_gost_3410_12_256_paramSetC },
> > + { "TCD", NID_id_tc26_gost_3410_12_256_paramSetD },
> >   { NULL, NID_undef },
> >  };
> >
> >  static const GostR3410_params GostR3410_512_params[] = {
> >   { "A",  NID_id_tc26_gost_3410_12_512_paramSetA },
> >   { "B",  NID_id_tc26_gost_3410_12_512_paramSetB },
> > + { "TCA", NID_id_tc26_gost_3410_12_512_paramSetA },
> > + { "TCB", NID_id_tc26_gost_3410_12_512_paramSetB },
> > + { "TCC", NID_id_tc26_gost_3410_12_512_paramSetC },
> >   { NULL, NID_undef },
> >  };
> >
> > --
> > 2.25.1
> >



-- 
With best wishes
Dmitry



[PATCH 6/8] ssl: do not send GOST 94 certificate type

2020-03-28 Thread Dmitry Baryshkov
GOST R 34.10-94 is an obsolete certificate type, unsupported by
LibreSSL and by the rest of current software, so there is no point in
sending in the CertificateTypes. Drop it.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libssl/s3_lib.c | 2 --
 src/lib/libssl/tls1.h   | 1 -
 2 files changed, 3 deletions(-)

diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index dfd5893a2fa7..f71995632040 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -2549,8 +2549,6 @@ ssl3_get_req_cert_types(SSL *s, CBB *cbb)
 
 #ifndef OPENSSL_NO_GOST
if ((alg_k & SSL_kGOST) != 0) {
-   if (!CBB_add_u8(cbb, TLS_CT_GOST94_SIGN))
-   return 0;
if (!CBB_add_u8(cbb, TLS_CT_GOST01_SIGN))
return 0;
if (!CBB_add_u8(cbb, TLS_CT_GOST12_256_SIGN))
diff --git a/src/lib/libssl/tls1.h b/src/lib/libssl/tls1.h
index 2230f0bab8b9..26dca0803434 100644
--- a/src/lib/libssl/tls1.h
+++ b/src/lib/libssl/tls1.h
@@ -738,7 +738,6 @@ 
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 #define TLS_CT_ECDSA_SIGN  64
 #define TLS_CT_RSA_FIXED_ECDH  65
 #define TLS_CT_ECDSA_FIXED_ECDH66
-#define TLS_CT_GOST94_SIGN 21
 #define TLS_CT_GOST01_SIGN 22
 #define TLS_CT_GOST12_256_SIGN 238 /* FIXME: IANA */
 #define TLS_CT_GOST12_512_SIGN 239 /* FIXME: IANA */
-- 
2.25.1



[PATCH 7/8] ssl: add support for IANA-allocated GOST certificate types

2020-03-28 Thread Dmitry Baryshkov
IANA has allocated numbers for GOST ClientCertificateType. Use them in
addition to private values (left in place for compat).

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libssl/s3_lib.c | 4 
 src/lib/libssl/tls1.h   | 6 --
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index f71995632040..671d86e8cc14 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -2555,6 +2555,10 @@ ssl3_get_req_cert_types(SSL *s, CBB *cbb)
return 0;
if (!CBB_add_u8(cbb, TLS_CT_GOST12_512_SIGN))
return 0;
+   if (!CBB_add_u8(cbb, TLS_CT_GOST12_256_SIGN_COMPAT))
+   return 0;
+   if (!CBB_add_u8(cbb, TLS_CT_GOST12_512_SIGN_COMPAT))
+   return 0;
}
 #endif
 
diff --git a/src/lib/libssl/tls1.h b/src/lib/libssl/tls1.h
index 26dca0803434..b7d7fe48a27d 100644
--- a/src/lib/libssl/tls1.h
+++ b/src/lib/libssl/tls1.h
@@ -739,8 +739,10 @@ 
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 #define TLS_CT_RSA_FIXED_ECDH  65
 #define TLS_CT_ECDSA_FIXED_ECDH66
 #define TLS_CT_GOST01_SIGN 22
-#define TLS_CT_GOST12_256_SIGN 238 /* FIXME: IANA */
-#define TLS_CT_GOST12_512_SIGN 239 /* FIXME: IANA */
+#define TLS_CT_GOST12_256_SIGN 67
+#define TLS_CT_GOST12_512_SIGN 68
+#define TLS_CT_GOST12_256_SIGN_COMPAT  238 /* pre-IANA, for compat */
+#define TLS_CT_GOST12_512_SIGN_COMPAT  239 /* pre-IANA, for compat */
 /* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
  * comment there) */
 #define TLS_CT_NUMBER  11
-- 
2.25.1



[PATCH 1/8] ssl_sigalgs: select proper default algorithm for GOST pkeys

2020-03-28 Thread Dmitry Baryshkov
Return default sigalg algorithm depending in the default digest
algorithm (GOST94 or Streebog) selected by pkey.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libssl/ssl_sigalgs.c   | 43 --
 src/regress/lib/libssl/tlsext/tlsexttest.c | 10 +++--
 2 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/src/lib/libssl/ssl_sigalgs.c b/src/lib/libssl/ssl_sigalgs.c
index 37fdcfa73fcb..0bf72aea21f0 100644
--- a/src/lib/libssl/ssl_sigalgs.c
+++ b/src/lib/libssl/ssl_sigalgs.c
@@ -40,7 +40,7 @@ const struct ssl_sigalg sigalgs[] = {
{
.value = SIGALG_GOSTR12_512_STREEBOG_512,
.md = EVP_streebog512,
-   .key_type = EVP_PKEY_GOSTR12_512,
+   .key_type = EVP_PKEY_GOSTR01,
},
 #endif
{
@@ -69,7 +69,7 @@ const struct ssl_sigalg sigalgs[] = {
{
.value = SIGALG_GOSTR12_256_STREEBOG_256,
.md = EVP_streebog256,
-   .key_type = EVP_PKEY_GOSTR12_256,
+   .key_type = EVP_PKEY_GOSTR01,
},
{
.value = SIGALG_GOSTR01_GOST94,
@@ -170,6 +170,11 @@ uint16_t tls12_sigalgs[] = {
SIGALG_ECDSA_SECP256R1_SHA256,
SIGALG_RSA_PKCS1_SHA1, /* XXX */
SIGALG_ECDSA_SHA1, /* XXX */
+#ifndef OPENSSL_NO_GOST
+   SIGALG_GOSTR12_512_STREEBOG_512,
+   SIGALG_GOSTR12_256_STREEBOG_256,
+   SIGALG_GOSTR01_GOST94,
+#endif
 };
 size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0]));
 
@@ -254,9 +259,39 @@ ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, 
EVP_PKEY *pkey,
}
}
 
+#ifndef OPENSSL_NO_GOST
+   if (pkey->type == EVP_PKEY_GOSTR01) {
+   int nid;
+
+   if (!EVP_PKEY_get_default_digest_nid(pkey, ))
+   return 0;
+
+   return EVP_MD_type(sigalg->md()) == nid;
+   }
+#endif
+
return 1;
 }
 
+#ifndef OPENSSL_NO_GOST
+static const struct ssl_sigalg *
+ssl_sigalg_gost_select(SSL *s, EVP_PKEY *pkey)
+{
+   int nid = NID_id_GostR3411_94;
+
+   if (!EVP_PKEY_get_default_digest_nid(pkey, )) {
+   SSLerror(s, ERR_R_EVP_LIB);
+   /* fallthrough, return GOST94 */
+   }
+   if (nid == NID_id_tc26_gost3411_2012_256)
+   return ssl_sigalg_lookup(SIGALG_GOSTR12_256_STREEBOG_256);
+   else if (nid == NID_id_tc26_gost3411_2012_512)
+   return ssl_sigalg_lookup(SIGALG_GOSTR12_512_STREEBOG_512);
+   else
+   return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
+}
+#endif
+
 const struct ssl_sigalg *
 ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
 {
@@ -280,7 +315,7 @@ ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
 #ifndef OPENSSL_NO_GOST
case EVP_PKEY_GOSTR01:
-   return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
+   return ssl_sigalg_gost_select(s, pkey);
 #endif
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
@@ -300,7 +335,7 @@ ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
 #ifndef OPENSSL_NO_GOST
case EVP_PKEY_GOSTR01:
-   return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
+   return ssl_sigalg_gost_select(s, pkey);
 #endif
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c 
b/src/regress/lib/libssl/tlsext/tlsexttest.c
index c15724da29a4..0fed69b29cc4 100644
--- a/src/regress/lib/libssl/tlsext/tlsexttest.c
+++ b/src/regress/lib/libssl/tlsext/tlsexttest.c
@@ -1505,9 +1505,10 @@ test_tlsext_ri_server(void)
  */
 
 static unsigned char tlsext_sigalgs_client[] = {
-   0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06, 0x03,
+   0x00, 0x1c, 0x08, 0x06, 0x06, 0x01, 0x06, 0x03,
0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04,
0x04, 0x01, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03,
+   0xef, 0xef, 0xee, 0xee, 0xed, 0xed,
 };
 
 static int
@@ -2712,13 +2713,14 @@ test_tlsext_srtp_server(void)
 #endif /* OPENSSL_NO_SRTP */
 
 unsigned char tlsext_clienthello_default[] = {
-   0x00, 0x32, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
+   0x00, 0x38, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d,
0x00, 0x17, 0x00, 0x18, 0x00, 0x23, 0x00, 0x00,
-   0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x08, 0x06,
+   0x00, 0x0d, 0x00, 0x1e, 0x00, 0x1c, 0x08, 0x06,
0x06, 0x01, 0x06, 0x03, 0x08, 0x05, 0x05, 0x01,
0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04, 0x03,
-   0x02, 0x01, 0x02, 0x03,
+   0x02, 0x01, 0x02, 0x03, 0xef, 0xef, 0xee, 0xee,
+   0xed, 0xed,
 };
 
 unsigned char tlsext_clienthello_disabled[] = {};
-- 
2.25.1



[PATCH 5/8] ssl: support GOST certificates in ssl_cert_dup()

2020-03-28 Thread Dmitry Baryshkov
Add case entry for SSL_PKEY_GOST01

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libssl/ssl_cert.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/lib/libssl/ssl_cert.c b/src/lib/libssl/ssl_cert.c
index af8ef329b4b2..4da453c11eca 100644
--- a/src/lib/libssl/ssl_cert.c
+++ b/src/lib/libssl/ssl_cert.c
@@ -253,6 +253,10 @@ ssl_cert_dup(CERT *cert)
/* We have an ECC key */
break;
 
+   case SSL_PKEY_GOST01:
+   /* We have a GOST key */
+   break;
+
default:
/* Can't happen. */
SSLerrorx(SSL_R_LIBRARY_BUG);
-- 
2.25.1



[PATCH 8/8] ssl: add support for new GOST CNT-IMIT ciphersuite value

2020-03-28 Thread Dmitry Baryshkov
Add support for IANA-assigned value {0xc1, 0x02} for GOST CNT-IMIT
CipherSuite (GOST2012256-GOST89-GOST89).

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libssl/s3_lib.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index 671d86e8cc14..662df29ae91e 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1305,6 +1305,23 @@ SSL_CIPHER ssl3_ciphers[] = {
.alg_bits = 256,
},
 
+   /* Cipher C102 */
+   {
+   .valid = 1,
+   .name = "GOST2012256-GOST89-GOST89",
+   .id = 0x300c102,
+   .algorithm_mkey = SSL_kGOST,
+   .algorithm_auth = SSL_aGOST01,
+   .algorithm_enc = SSL_eGOST2814789CNT,
+   .algorithm_mac = SSL_GOST89MAC,
+   .algorithm_ssl = SSL_TLSV1_2,
+   .algo_strength = SSL_HIGH,
+   .algorithm2 = 
SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256|
+   TLS1_STREAM_MAC,
+   .strength_bits = 256,
+   .alg_bits = 256
+   },
+
/* Cipher CCA8 */
{
.valid = 1,
-- 
2.25.1



[PATCH 3/8] ssl: add support for IANA-allocated GOST sigalgs values

2020-03-28 Thread Dmitry Baryshkov
Add support for IANA-allocated GOST SignatureAlgorithms values. Values
predating IANA allocation are left in place because they are still used
by deployed products.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libssl/ssl_sigalgs.c | 12 
 src/lib/libssl/ssl_sigalgs.h |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/src/lib/libssl/ssl_sigalgs.c b/src/lib/libssl/ssl_sigalgs.c
index 0bf72aea21f0..f4d5f5bc5621 100644
--- a/src/lib/libssl/ssl_sigalgs.c
+++ b/src/lib/libssl/ssl_sigalgs.c
@@ -37,6 +37,11 @@ const struct ssl_sigalg sigalgs[] = {
.curve_nid = NID_secp521r1,
},
 #ifndef OPENSSL_NO_GOST
+   {
+   .value = SIGALG_GOSTR12_512,
+   .md = EVP_streebog512,
+   .key_type = EVP_PKEY_GOSTR01,
+   },
{
.value = SIGALG_GOSTR12_512_STREEBOG_512,
.md = EVP_streebog512,
@@ -66,6 +71,11 @@ const struct ssl_sigalg sigalgs[] = {
.curve_nid = NID_X9_62_prime256v1,
},
 #ifndef OPENSSL_NO_GOST
+   {
+   .value = SIGALG_GOSTR12_256,
+   .md = EVP_streebog256,
+   .key_type = EVP_PKEY_GOSTR01,
+   },
{
.value = SIGALG_GOSTR12_256_STREEBOG_256,
.md = EVP_streebog256,
@@ -171,7 +181,9 @@ uint16_t tls12_sigalgs[] = {
SIGALG_RSA_PKCS1_SHA1, /* XXX */
SIGALG_ECDSA_SHA1, /* XXX */
 #ifndef OPENSSL_NO_GOST
+   SIGALG_GOSTR12_512,
SIGALG_GOSTR12_512_STREEBOG_512,
+   SIGALG_GOSTR12_256,
SIGALG_GOSTR12_256_STREEBOG_256,
SIGALG_GOSTR01_GOST94,
 #endif
diff --git a/src/lib/libssl/ssl_sigalgs.h b/src/lib/libssl/ssl_sigalgs.h
index 13a3597fb5a3..5fe3fc3bb27c 100644
--- a/src/lib/libssl/ssl_sigalgs.h
+++ b/src/lib/libssl/ssl_sigalgs.h
@@ -42,6 +42,8 @@ __BEGIN_HIDDEN_DECLS
 #define SIGALG_RSA_PSS_PSS_SHA256  0x0809
 #define SIGALG_RSA_PSS_PSS_SHA384  0x080a
 #define SIGALG_RSA_PSS_PSS_SHA512  0x080b
+#define SIGALG_GOSTR12_256 0x0840
+#define SIGALG_GOSTR12_512 0x0841
 #define SIGALG_RSA_PKCS1_SHA1  0x0201
 #define SIGALG_ECDSA_SHA1  0x0203
 #define SIGALG_PRIVATE_START   0xFE00
-- 
2.25.1



[PATCH 2/8] ssl: pass a flag to GOST pkey to generate proper TLS1.2 CertVerify

2020-03-28 Thread Dmitry Baryshkov
GOST cipher suites requires to generate CertVerify signatures in a
special way (see ssl3_send_client_kex_gost(), ssl3_get_cert_verify()).
However a flag GOST_SIG_FORMAT_RS_LE was not passed in case of TLS 1.2
connections (because they use different code path). Pass this flag to
the PKEY if it is a GOST pkey.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libssl/ssl_clnt.c | 7 +++
 src/lib/libssl/ssl_srvr.c | 7 +++
 2 files changed, 14 insertions(+)

diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c
index ce43a89ca737..2a16bd19f247 100644
--- a/src/lib/libssl/ssl_clnt.c
+++ b/src/lib/libssl/ssl_clnt.c
@@ -2345,6 +2345,13 @@ ssl3_send_client_verify_sigalgs(SSL *s, CBB *cert_verify)
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
+   if (sigalg->key_type == NID_id_GostR3410_2001 &&
+   EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+ EVP_PKEY_CTRL_GOST_SIG_FORMAT,
+ GOST_SIG_FORMAT_RS_LE, NULL) <= 0) {
+   SSLerror(s, ERR_R_EVP_LIB);
+   goto err;
+   }
if ((sigalg->flags & SIGALG_FLAG_RSA_PSS) &&
(!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
!EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1))) {
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index c9c24f0453bd..2fe634de30d3 100644
--- a/src/lib/libssl/ssl_srvr.c
+++ b/src/lib/libssl/ssl_srvr.c
@@ -2182,6 +2182,13 @@ ssl3_get_cert_verify(SSL *s)
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
+   if (sigalg->key_type == NID_id_GostR3410_2001 &&
+   EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_VERIFY,
+ EVP_PKEY_CTRL_GOST_SIG_FORMAT,
+ GOST_SIG_FORMAT_RS_LE, NULL) <= 0) {
+   al = SSL_AD_INTERNAL_ERROR;
+   goto f_err;
+   }
if (!EVP_DigestVerifyUpdate(, hdata, hdatalen)) {
SSLerror(s, ERR_R_EVP_LIB);
al = SSL_AD_INTERNAL_ERROR;
-- 
2.25.1



[PATCH 4/8] ssl: provide interoperability with CryptoPro CSP

2020-03-28 Thread Dmitry Baryshkov
Windows CSPs fail to send proper SigAlgs extension (it does not include
GOST entries even for GOST CipherSuites). To ensure interoperability,
assume that the server will understand GOST sigalgs if it has sent GOST
certificate.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libssl/ssl_sigalgs.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/src/lib/libssl/ssl_sigalgs.c b/src/lib/libssl/ssl_sigalgs.c
index f4d5f5bc5621..ccf955b4c501 100644
--- a/src/lib/libssl/ssl_sigalgs.c
+++ b/src/lib/libssl/ssl_sigalgs.c
@@ -373,6 +373,15 @@ ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
return sigalg;
}
 
+#ifndef OPENSSL_NO_GOST
+   /* Windows CSPs fail to send proper SigAlgs extension (it does not
+* include GOST entries even for GOST CipherSuites). To ensure
+* interoperability, assume that the server will understand GOST
+* sigalgs if it has sent GOST certificate. */
+   if (pkey->type == EVP_PKEY_GOSTR01)
+   return ssl_sigalg_gost_select(s, pkey);
+#endif
+
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
return NULL;
 }
-- 
2.25.1



[PATCH v2 2/2] gost: populate params tables with new curves

2020-03-28 Thread Dmitry Baryshkov
Allow users to specify new curves via strings.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gostr341001_params.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/src/lib/libcrypto/gost/gostr341001_params.c 
b/src/lib/libcrypto/gost/gostr341001_params.c
index 13054cd0fc26..0f068d97eb0a 100644
--- a/src/lib/libcrypto/gost/gostr341001_params.c
+++ b/src/lib/libcrypto/gost/gostr341001_params.c
@@ -94,12 +94,19 @@ static const GostR3410_params GostR3410_256_params[] = {
{ "0",  NID_id_GostR3410_2001_TestParamSet },
{ "XA", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
{ "XB", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
+   { "TCA", NID_id_tc26_gost_3410_12_256_paramSetA },
+   { "TCB", NID_id_tc26_gost_3410_12_256_paramSetB },
+   { "TCC", NID_id_tc26_gost_3410_12_256_paramSetC },
+   { "TCD", NID_id_tc26_gost_3410_12_256_paramSetD },
{ NULL, NID_undef },
 };
 
 static const GostR3410_params GostR3410_512_params[] = {
{ "A",  NID_id_tc26_gost_3410_12_512_paramSetA },
{ "B",  NID_id_tc26_gost_3410_12_512_paramSetB },
+   { "TCA", NID_id_tc26_gost_3410_12_512_paramSetA },
+   { "TCB", NID_id_tc26_gost_3410_12_512_paramSetB },
+   { "TCC", NID_id_tc26_gost_3410_12_512_paramSetC },
{ NULL, NID_undef },
 };
 
-- 
2.25.1



[PATCH v2 1/2] ec: add support for several more GOST curves

2020-03-28 Thread Dmitry Baryshkov
Add support for GOST curves defined by RFC 7836 and
draft-deremin-rfc4491-bis. Add aliases for 256-bit GOST curves (see
draft-smyshlyaev-tls12-gost-suites). 512-bit curve ids were renamed to
follow names defined in tc26 OID registry.
(https://tc26.ru/about/protsedury-i-reglamenty/identifikatory-obektov-oid-tekhnicheskogo-komiteta-po-standartizatsii-kriptograficheskaya-zashchita-1.html)

Sponsored by ROSA Linux.

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/ec/ec_curve.c | 162 +++-
 src/lib/libcrypto/gost/gostr341001_params.c |   4 +-
 src/lib/libcrypto/objects/obj_mac.num   |  10 +-
 src/lib/libcrypto/objects/objects.txt   |  10 +-
 4 files changed, 176 insertions(+), 10 deletions(-)

diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c
index e075b1ed3ea5..830bb47b3d0b 100644
--- a/src/lib/libcrypto/ec/ec_curve.c
+++ b/src/lib/libcrypto/ec/ec_curve.c
@@ -2900,11 +2900,103 @@ static const struct {
}
 };
 
+/* This curve is defined in two birationally equal forms: canonical and Twisted
+ * Edwards. We do calculations in canonical (Weierstrass) form. */
+static const struct {
+   EC_CURVE_DATA h;
+   unsigned char data[0 + 32 * 6];
+}
+ _EC_GOST_2012_256_TC26_A = {
+   {
+   NID_X9_62_prime_field, 0, 32, 4
+   },
+   {   /* no seed */
+   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
/* p */
+   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+   0xFD, 0x97,
+   0xc2, 0x17, 0x3f, 0x15, 0x13, 0x98, 0x16, 0x73, 0xaf, 0x48, 
/* a */
+   0x92, 0xc2, 0x30, 0x35, 0xa2, 0x7c, 0xe2, 0x5e, 0x20, 0x13,
+   0xbf, 0x95, 0xaa, 0x33, 0xb2, 0x2c, 0x65, 0x6f, 0x27, 0x7e,
+   0x73, 0x35,
+   0x29, 0x5f, 0x9b, 0xae, 0x74, 0x28, 0xed, 0x9c, 0xcc, 0x20, 
/* b */
+   0xe7, 0xc3, 0x59, 0xa9, 0xd4, 0x1a, 0x22, 0xfc, 0xcd, 0x91,
+   0x08, 0xe1, 0x7b, 0xf7, 0xba, 0x93, 0x37, 0xa6, 0xf8, 0xae,
+   0x95, 0x13,
+   0x91, 0xe3, 0x84, 0x43, 0xa5, 0xe8, 0x2c, 0x0d, 0x88, 0x09, 
/* x */
+   0x23, 0x42, 0x57, 0x12, 0xb2, 0xbb, 0x65, 0x8b, 0x91, 0x96,
+   0x93, 0x2e, 0x02, 0xc7, 0x8b, 0x25, 0x82, 0xfe, 0x74, 0x2d,
+   0xaa, 0x28,
+   0x32, 0x87, 0x94, 0x23, 0xab, 0x1a, 0x03, 0x75, 0x89, 0x57, 
/* y */
+   0x86, 0xc4, 0xbb, 0x46, 0xe9, 0x56, 0x5f, 0xde, 0x0b, 0x53,
+   0x44, 0x76, 0x67, 0x40, 0xaf, 0x26, 0x8a, 0xdb, 0x32, 0x32,
+   0x2e, 0x5c,
+   0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
/* order */
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd8, 0xcd, 0xdf,
+   0xc8, 0x7b, 0x66, 0x35, 0xc1, 0x15, 0xaf, 0x55, 0x6c, 0x36,
+   0x0c, 0x67,
+   }
+};
+
 static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 64 * 6];
 }
- _EC_GOST_2012_TC26_A = {
+ _EC_GOST_2012_512_Test = {
+   {
+   NID_X9_62_prime_field, 0, 64, 1
+   },
+   {   /* no seed */
+   0x45, 0x31, 0xac, 0xd1, 0xfe, 0x00, 0x23, 0xc7, 0x55, 0x0d, 
/* p */
+   0x26, 0x7b, 0x6b, 0x2f, 0xee, 0x80, 0x92, 0x2b, 0x14, 0xb2,
+   0xff, 0xb9, 0x0f, 0x04, 0xd4, 0xeb, 0x7c, 0x09, 0xb5, 0xd2,
+   0xd1, 0x5d, 0xf1, 0xd8, 0x52, 0x74, 0x1a, 0xf4, 0x70, 0x4a,
+   0x04, 0x58, 0x04, 0x7e, 0x80, 0xe4, 0x54, 0x6d, 0x35, 0xb8,
+   0x33, 0x6f, 0xac, 0x22, 0x4d, 0xd8, 0x16, 0x64, 0xbb, 0xf5,
+   0x28, 0xbe, 0x63, 0x73,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
/* a */
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x07,
+   0x1c, 0xff, 0x08, 0x06, 0xa3, 0x11, 0x16, 0xda, 0x29, 0xd8, 
/* b */
+   0xcf, 0xa5, 0x4e, 0x57, 0xeb, 0x74, 0x8b, 0xc5, 0xf3, 0x77,
+   0xe4, 0x94, 0x00, 0xfd, 0xd7, 0x88, 0xb6, 0x49, 0xec, 0xa1,
+   0xac, 0x43, 0x61, 0x83, 0x40, 0x13, 0xb2, 0xad, 0x73, 0x22,
+   0x48, 0x0a, 0x89, 0xca, 0x58, 0xe0, 0xcf, 0x74, 0xbc, 0x9e,
+   0x54, 0x0c, 0x2a, 0xdd, 0x68, 0x97, 0xfa, 0xd0, 0xa3, 0x08,
+   0x4f, 0x30, 0x2a, 0xdc,
+   0x24, 0xd1, 0x9c, 0xc6, 0x45, 0x72, 0xee, 0x30, 0xf3, 0x96, 
/* x */
+   0xbf, 0x6e, 0xbb, 0xfd, 0x7a, 0x6c, 0x52, 0x13, 0xb3, 0xb3,
+   0xd7

Re: [PATCH] ec: add support for several more GOST curves

2020-03-28 Thread Dmitry Baryshkov
сб, 28 мар. 2020 г. в 11:30, Kinichiro Inoguchi :
>
> Hi,
>
> I have a 3 questions,
> - parameter set values for Twisted Edwards
> - description in _ec_list_element_st
> - naming about object identifier
>
> details are described below.
>
>
> On Thu, Mar 26, 2020 at 09:25:57PM +0300, dbarysh...@gmail.com wrote:
> > From: Dmitry Baryshkov 
> >
> > Add support for GOST curves defined by RFC 7836 and
> > draft-deremin-rfc4491-bis. Add aliases for 256-bit GOST curves (see
> > draft-smyshlyaev-tls12-gost-suites).
> >
> > Sponsored by ROSA Linux.
> >
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >  src/lib/libcrypto/ec/ec_curve.c   | 158 +-
> >  src/lib/libcrypto/objects/obj_mac.num |   6 +
> >  src/lib/libcrypto/objects/objects.txt |  10 +-
> >  3 files changed, 168 insertions(+), 6 deletions(-)
> >
> > diff --git a/src/lib/libcrypto/ec/ec_curve.c 
> > b/src/lib/libcrypto/ec/ec_curve.c
> > index e075b1ed3ea5..a1bc88ee2cc6 100644
> > --- a/src/lib/libcrypto/ec/ec_curve.c
> > +++ b/src/lib/libcrypto/ec/ec_curve.c
> > @@ -2900,11 +2900,101 @@ static const struct {
> >   }
> >  };
> >
> > +static const struct {
> > + EC_CURVE_DATA h;
> > + unsigned char data[0 + 32 * 6];
> > +}
> > + _EC_GOST_2012_256_TC26_A = {
> > + {
> > + NID_X9_62_prime_field, 0, 32, 1
> > + },
> > + {   /* no seed */
> > + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   
> >   /* p */
> > + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
> > + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
> > + 0xFD, 0x97,
> > + 0xc2, 0x17, 0x3f, 0x15, 0x13, 0x98, 0x16, 0x73, 0xaf, 0x48,   
> >   /* a */
> > + 0x92, 0xc2, 0x30, 0x35, 0xa2, 0x7c, 0xe2, 0x5e, 0x20, 0x13,
> > + 0xbf, 0x95, 0xaa, 0x33, 0xb2, 0x2c, 0x65, 0x6f, 0x27, 0x7e,
> > + 0x73, 0x35,
> > + 0x29, 0x5f, 0x9b, 0xae, 0x74, 0x28, 0xed, 0x9c, 0xcc, 0x20,   
> >   /* b */
> > + 0xe7, 0xc3, 0x59, 0xa9, 0xd4, 0x1a, 0x22, 0xfc, 0xcd, 0x91,
> > + 0x08, 0xe1, 0x7b, 0xf7, 0xba, 0x93, 0x37, 0xa6, 0xf8, 0xae,
> > + 0x95, 0x13,
> > + 0x91, 0xe3, 0x84, 0x43, 0xa5, 0xe8, 0x2c, 0x0d, 0x88, 0x09,   
> >   /* x */
> > + 0x23, 0x42, 0x57, 0x12, 0xb2, 0xbb, 0x65, 0x8b, 0x91, 0x96,
> > + 0x93, 0x2e, 0x02, 0xc7, 0x8b, 0x25, 0x82, 0xfe, 0x74, 0x2d,
> > + 0xaa, 0x28,
> > + 0x32, 0x87, 0x94, 0x23, 0xab, 0x1a, 0x03, 0x75, 0x89, 0x57,   
> >   /* y */
> > + 0x86, 0xc4, 0xbb, 0x46, 0xe9, 0x56, 0x5f, 0xde, 0x0b, 0x53,
> > + 0x44, 0x76, 0x67, 0x40, 0xaf, 0x26, 0x8a, 0xdb, 0x32, 0x32,
> > + 0x2e, 0x5c,
> > + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   
> >   /* order */
> > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd8, 0xcd, 0xdf,
> > + 0xc8, 0x7b, 0x66, 0x35, 0xc1, 0x15, 0xaf, 0x55, 0x6c, 0x36,
> > + 0x0c, 0x67,
> > + }
> > +};
> > +
>
>
> This diff adds * below, and 2 Twisted Edwards one misses m,e,d,u,v.
> Is this as you expected for now ?
>
>   Canonical:
>   *id-tc26-gost-3410-2012-512-paramSetTest order = m = q
>id-tc26-gost-3410-2012-512-paramSetAorder = m = q
>id-tc26-gost-3410-2012-512-paramSetBorder = m = q
>
>   Twisted Edwards:
>   *id-tc26-gost-3410-2012-512-paramSetCorder = q, misses m,e,d,u,v
>   *id-tc26-gost-3410-2012-256-paramSetAorder = q, misses m,e,d,u,v

This is expected. These curves are defined in Weierstrass form (a, b,
x, y) and in birationally equivalent Twisted Edwards form (e, d, u,
v). One can perform calculations in any of these forms. In this RFC m
= order of a whole curve, q is an order of the subgroup. Version 2 of
the patch will fix cofactors.


> >  #endif
> >
> >  typedef struct _ec_list_element_st {
> > @@ -3147,8 +3291,14 @@ static const ec_list_element curve_list[] = {
> >   {NID_id_GostR3410_2001_CryptoPro_C_ParamSet, 
> > &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2001 CryptoPro-C"},
> >   {NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, 
> > &_EC_GOST_2001_CryptoPro_A.h, 0, "GOST R 34.10-2001 CryptoPro-XchA"},
> >   {NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, 
> > &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2001 CryptoPro-XchB"},
> > -  

[PATCH] gostr341001: support unwrapped private keys support

2020-03-26 Thread Dmitry Baryshkov
GOST private keys can be wrapped in OCTET STRING, INTEGER or come
unwrapped. Support the latter format.

Sponsored by ROSA Linux

Signed-off-by: Dmitry Baryshkov 
---
 src/lib/libcrypto/gost/gostr341001_ameth.c | 75 --
 1 file changed, 70 insertions(+), 5 deletions(-)

diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c 
b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 0f816377dde1..70bd3357f184 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -437,6 +437,56 @@ priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int 
indent, ASN1_PCTX *pctx)
return pub_print_gost01(out, pkey, indent, pctx);
 }
 
+static BIGNUM *unmask_priv_key(EVP_PKEY *pk,
+   const unsigned char *buf, int len, int num_masks)
+{
+   BIGNUM *pknum_masked = NULL, *q = NULL;
+   const GOST_KEY *key_ptr = pk->pkey.gost;
+   const EC_GROUP *group = GOST_KEY_get0_group(key_ptr);
+
+   pknum_masked = GOST_le2bn(buf, len, NULL);
+   if (!pknum_masked) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   return NULL;
+   }
+
+   if (num_masks > 0) {
+   /*
+* XXX Remove sign by gost94
+*/
+   const unsigned char *p = buf + num_masks * len;
+
+   q = BN_new();
+   if (!q) {
+   GOSTerror(ERR_R_MALLOC_FAILURE);
+   BN_free(pknum_masked);
+   pknum_masked = NULL;
+   goto end;
+   }
+   if (EC_GROUP_get_order(group, q, NULL) <= 0) {
+   GOSTerror(ERR_R_EC_LIB);
+   BN_free(pknum_masked);
+   pknum_masked = NULL;
+   goto end;
+   }
+
+   for (; p != buf; p -= len) {
+   BIGNUM *mask = GOST_le2bn(p, len, NULL);
+   BN_CTX *ctx = BN_CTX_new();
+
+   BN_mod_mul(pknum_masked, pknum_masked, mask, q, ctx);
+
+   BN_CTX_free(ctx);
+   BN_free(mask);
+   }
+   }
+
+end:
+   if (q)
+   BN_free(q);
+   return pknum_masked;
+}
+
 static int
 priv_decode_gost01(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf)
 {
@@ -450,6 +500,7 @@ priv_decode_gost01(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO 
*p8inf)
GOST_KEY *ec;
int ptype = V_ASN1_UNDEF;
ASN1_STRING *pval = NULL;
+   int expected_key_len;
 
if (PKCS8_pkey_get0(_obj, _buf, _len, , p8inf) == 
0) {
GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
@@ -467,29 +518,43 @@ priv_decode_gost01(EVP_PKEY *pk, const 
PKCS8_PRIV_KEY_INFO *p8inf)
return 0;
}
p = pkey_buf;
-   if (V_ASN1_OCTET_STRING == *p) {
+
+   expected_key_len = (pkey_bits_gost01(pk) + 7) / 8;
+   if (expected_key_len == 0) {
+   EVPerror(EVP_R_DECODE_ERROR);
+   return 0;
+   } else if (priv_len % expected_key_len == 0) {
+   /* Key is not wrapped but masked */
+   pk_num = unmask_priv_key(pk, pkey_buf, expected_key_len,
+   priv_len / expected_key_len - 1);
+   } else if (V_ASN1_OCTET_STRING == *p) {
/* New format - Little endian octet string */
ASN1_OCTET_STRING *s =
d2i_ASN1_OCTET_STRING(NULL, , priv_len);
 
if (s == NULL) {
-   GOSTerror(EVP_R_DECODE_ERROR);
+   EVPerror(EVP_R_DECODE_ERROR);
ASN1_STRING_free(s);
return 0;
}
 
pk_num = GOST_le2bn(s->data, s->length, NULL);
ASN1_STRING_free(s);
-   } else {
+   } else if (V_ASN1_INTEGER == *p) {
priv_key = d2i_ASN1_INTEGER(NULL, , priv_len);
-   if (priv_key == NULL)
+   if (priv_key == NULL) {
+   EVPerror(EVP_R_DECODE_ERROR);
return 0;
+   }
ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL);
ASN1_INTEGER_free(priv_key);
if (ret == 0) {
-   GOSTerror(EVP_R_DECODE_ERROR);
+   EVPerror(EVP_R_DECODE_ERROR);
return 0;
}
+   } else {
+   EVPerror(EVP_R_DECODE_ERROR);
+   return 0;
}
 
ec = pk->pkey.gost;
-- 
2.25.1