Add gost-new patches sponsored by ROSA Linux

TODO: add tests
This commit is contained in:
Mikhail Novosyolov 2020-08-05 12:55:25 +03:00
parent ce2e67e4c2
commit faac7d3eaa
99 changed files with 28596 additions and 39 deletions

View file

@ -1,2 +1,3 @@
sources: sources:
libressl-3.2.0.tar.gz: de3c762ffaba7c60101f92d2a419e886a199de03 libressl-openbsd-768c7156952b7df8245172586ca8c4c37d599a47.tar.gz: ab8c29e38a759d6b1c9d0abe1da99984ddcfdce2
libressl-portable-44a6a2397fb9b8d6868ef73d51e6ef79c39b0322.tar.gz: 18b8a78ec08f4224f2ee590b0ded804481a2b932

View file

@ -1,7 +1,7 @@
From 4074611c49806fa5e8937a5aa24d9084235a89a5 Mon Sep 17 00:00:00 2001 From d2e4509e4ce2b6b622291a9879e41dc0717774a0 Mon Sep 17 00:00:00 2001
From: Mikhail Novosyolov <m.novosyolov@rosalinux.ru> From: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
Date: Fri, 29 Nov 2019 21:24:49 +0300 Date: Fri, 29 Nov 2019 21:24:49 +0300
Subject: [PATCH] Allow custom config location Subject: [PATCH 01/87] Allow custom config location
I want LibreSSL to: I want LibreSSL to:
- coexist with OpenSSL - coexist with OpenSSL
@ -52,5 +52,5 @@ index c9a2f34b2..313d6ecee 100644
return p; return p;
} }
-- --
2.20.1 2.17.1

View file

@ -0,0 +1,82 @@
From 23b68544c48ef0bc931b2693a32d45394cdac7b2 Mon Sep 17 00:00:00 2001
From: sthen <>
Date: Mon, 1 Jun 2020 18:53:53 +0000
Subject: [PATCH 02/87] Remove expired certificate, ok tb@ /C=SE/O=AddTrust
AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
src/lib/libcrypto/cert.pem | 54 +-------------------------------------
1 file changed, 1 insertion(+), 53 deletions(-)
diff --git a/src/lib/libcrypto/cert.pem b/src/lib/libcrypto/cert.pem
index c8531a781..de7633ce1 100644
--- a/src/lib/libcrypto/cert.pem
+++ b/src/lib/libcrypto/cert.pem
@@ -1,4 +1,4 @@
-# $OpenBSD: cert.pem,v 1.20 2020/04/10 12:13:17 sthen Exp $
+# $OpenBSD: cert.pem,v 1.21 2020/06/01 18:53:53 sthen Exp $
### /C=ES/CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
=== /C=ES/CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
@@ -350,58 +350,6 @@ LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
-----END CERTIFICATE-----
-### AddTrust AB
-
-=== /C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Validity
- Not Before: May 30 10:48:38 2000 GMT
- Not After : May 30 10:48:38 2020 GMT
- Subject: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
- X509v3 Key Usage:
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Authority Key Identifier:
- keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
- DirName:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
- serial:01
-
-SHA1 Fingerprint=02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68
-SHA256 Fingerprint=68:7F:A4:51:38:22:78:FF:F0:C8:B1:1F:8D:43:D5:76:67:1C:6E:B2:BC:EA:B4:13:FB:83:D9:65:D0:6D:2F:F2
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
-
### AffirmTrust
=== /C=US/O=AffirmTrust/CN=AffirmTrust Commercial
--
2.17.1

View file

@ -0,0 +1,562 @@
From 4136b433281acfa0808344e5db0f77ec981c30ee Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Wed, 3 Jun 2020 13:41:27 +0000
Subject: [PATCH 03/87] Properly document PKCS7_final(3), which was already
mentioned in passing in some other manual pages.
---
src/lib/libcrypto/man/Makefile | 3 +-
.../man/PEM_write_bio_PKCS7_stream.3 | 7 +-
src/lib/libcrypto/man/PKCS7_dataFinal.3 | 5 +-
src/lib/libcrypto/man/PKCS7_dataInit.3 | 25 ++-
src/lib/libcrypto/man/PKCS7_encrypt.3 | 14 +-
src/lib/libcrypto/man/PKCS7_final.3 | 201 ++++++++++++++++++
src/lib/libcrypto/man/PKCS7_sign.3 | 16 +-
src/lib/libcrypto/man/PKCS7_sign_add_signer.3 | 9 +-
src/lib/libcrypto/man/SMIME_write_PKCS7.3 | 8 +-
src/lib/libcrypto/man/i2d_PKCS7_bio_stream.3 | 7 +-
10 files changed, 263 insertions(+), 32 deletions(-)
create mode 100644 src/lib/libcrypto/man/PKCS7_final.3
diff --git a/src/lib/libcrypto/man/Makefile b/src/lib/libcrypto/man/Makefile
index 8af0c34d2..05b992e13 100644
--- a/src/lib/libcrypto/man/Makefile
+++ b/src/lib/libcrypto/man/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.164 2020/05/27 12:00:44 schwarze Exp $
+# $OpenBSD: Makefile,v 1.165 2020/06/03 13:41:27 schwarze Exp $
.include <bsd.own.mk>
@@ -218,6 +218,7 @@ MAN= \
PKCS7_dataInit.3 \
PKCS7_decrypt.3 \
PKCS7_encrypt.3 \
+ PKCS7_final.3 \
PKCS7_new.3 \
PKCS7_set_content.3 \
PKCS7_set_type.3 \
diff --git a/src/lib/libcrypto/man/PEM_write_bio_PKCS7_stream.3 b/src/lib/libcrypto/man/PEM_write_bio_PKCS7_stream.3
index 91a1a5cd5..dba2a42a7 100644
--- a/src/lib/libcrypto/man/PEM_write_bio_PKCS7_stream.3
+++ b/src/lib/libcrypto/man/PEM_write_bio_PKCS7_stream.3
@@ -1,5 +1,5 @@
-.\" $OpenBSD: PEM_write_bio_PKCS7_stream.3,v 1.9 2019/06/14 13:59:32 schwarze Exp $
-.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
+.\" $OpenBSD: PEM_write_bio_PKCS7_stream.3,v 1.10 2020/06/03 13:41:27 schwarze Exp $
+.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
.\" Copyright (c) 2007, 2009, 2016 The OpenSSL Project. All rights reserved.
@@ -48,7 +48,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 14 2019 $
+.Dd $Mdocdate: June 3 2020 $
.Dt PEM_WRITE_BIO_PKCS7_STREAM 3
.Os
.Sh NAME
@@ -81,6 +81,7 @@ otherwise 0 is returned and an error code can be retrieved with
.Xr BIO_new 3 ,
.Xr i2d_PKCS7_bio_stream 3 ,
.Xr PEM_write_PKCS7 3 ,
+.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr SMIME_write_PKCS7 3
.Sh HISTORY
diff --git a/src/lib/libcrypto/man/PKCS7_dataFinal.3 b/src/lib/libcrypto/man/PKCS7_dataFinal.3
index f9cdd62f6..e2e088d9d 100644
--- a/src/lib/libcrypto/man/PKCS7_dataFinal.3
+++ b/src/lib/libcrypto/man/PKCS7_dataFinal.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_dataFinal.3,v 1.1 2020/05/27 12:00:44 schwarze Exp $
+.\" $OpenBSD: PKCS7_dataFinal.3,v 1.2 2020/06/03 13:41:27 schwarze Exp $
.\"
.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 27 2020 $
+.Dd $Mdocdate: June 3 2020 $
.Dt PKCS7_DATAFINAL 3
.Os
.Sh NAME
@@ -134,6 +134,7 @@ but are silently skipped.
.Sh SEE ALSO
.Xr BIO_new 3 ,
.Xr PKCS7_dataInit 3 ,
+.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr PKCS7_sign 3
.Sh HISTORY
diff --git a/src/lib/libcrypto/man/PKCS7_dataInit.3 b/src/lib/libcrypto/man/PKCS7_dataInit.3
index 53090ff96..cb54d3f95 100644
--- a/src/lib/libcrypto/man/PKCS7_dataInit.3
+++ b/src/lib/libcrypto/man/PKCS7_dataInit.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_dataInit.3,v 1.1 2020/05/24 12:37:30 schwarze Exp $
+.\" $OpenBSD: PKCS7_dataInit.3,v 1.2 2020/06/03 13:41:27 schwarze Exp $
.\"
.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 24 2020 $
+.Dd $Mdocdate: June 3 2020 $
.Dt PKCS7_DATAINIT 3
.Os
.Sh NAME
@@ -110,6 +110,20 @@ are typically required to create
to choose its desired type, and to allocate the nested
.Vt ContentInfo
structure.
+Alternatively, for
+.Vt SignedData ,
+.Xr PKCS7_sign 3
+can be used with the
+.Dv PKCS7_PARTIAL
+or
+.Dv PKCS7_STREAM
+.Fa flags
+or for
+.Vt EnvelopedData ,
+.Xr PKCS7_encrypt 3
+with the
+.Dv PKCS7_STREAM
+flag.
.Pp
After calling
.Fn PKCS7_dataInit ,
@@ -130,7 +144,10 @@ does support the
.Vt EnvelopedData
and
.Vt SignedAndEnvelopedData
-types, using it for these types is awkward and error prone because
+types, using it for these types is awkward and error prone
+except when using
+.Xr PKCS7_encrypt 3
+for the setup because
.Xr PKCS7_content_new 3
does not support these two types.
So in addition to creating
@@ -183,6 +200,8 @@ or for various other reasons.
.Xr BIO_read 3 ,
.Xr PKCS7_content_new 3 ,
.Xr PKCS7_dataFinal 3 ,
+.Xr PKCS7_encrypt 3 ,
+.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr PKCS7_set_type 3 ,
.Xr PKCS7_sign 3
diff --git a/src/lib/libcrypto/man/PKCS7_encrypt.3 b/src/lib/libcrypto/man/PKCS7_encrypt.3
index 4d1b435f1..700498a1d 100644
--- a/src/lib/libcrypto/man/PKCS7_encrypt.3
+++ b/src/lib/libcrypto/man/PKCS7_encrypt.3
@@ -1,5 +1,5 @@
-.\" $OpenBSD: PKCS7_encrypt.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $
-.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
+.\" $OpenBSD: PKCS7_encrypt.3,v 1.11 2020/06/03 13:41:27 schwarze Exp $
+.\" full merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
.\" Copyright (c) 2002, 2006, 2007, 2008, 2009 The OpenSSL Project.
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 10 2019 $
+.Dd $Mdocdate: June 3 2020 $
.Dt PKCS7_ENCRYPT 3
.Os
.Sh NAME
@@ -133,11 +133,12 @@ properly finalize the
.Vt PKCS7
structure will give unpredictable results.
.Pp
-Several functions, including
+Several functions including
+.Xr PKCS7_final 3 ,
.Xr SMIME_write_PKCS7 3 ,
-.Xr i2d_PKCS7_bio_stream 3 ,
-and
.Xr PEM_write_bio_PKCS7_stream 3 ,
+and
+.Xr i2d_PKCS7_bio_stream 3
finalize the structure.
Alternatively finalization can be performed by obtaining the streaming
ASN.1
@@ -155,6 +156,7 @@ The error can be obtained from
.Xr ERR_get_error 3 .
.Sh SEE ALSO
.Xr PKCS7_decrypt 3 ,
+.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr PKCS7_sign 3
.Sh HISTORY
diff --git a/src/lib/libcrypto/man/PKCS7_final.3 b/src/lib/libcrypto/man/PKCS7_final.3
new file mode 100644
index 000000000..593483bb6
--- /dev/null
+++ b/src/lib/libcrypto/man/PKCS7_final.3
@@ -0,0 +1,201 @@
+.\" $OpenBSD: PKCS7_final.3,v 1.1 2020/06/03 13:41:27 schwarze Exp $
+.\"
+.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and 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.
+.\"
+.Dd $Mdocdate: June 3 2020 $
+.Dt PKCS7_FINAL 3
+.Os
+.Sh NAME
+.Nm PKCS7_final
+.Nd read data from a BIO into a ContentInfo object
+.Sh SYNOPSIS
+.In openssl/pkcs7.h
+.Ft int
+.Fo PKCS7_final
+.Fa "PKCS7 *p7"
+.Fa "BIO *data"
+.Fa "int flags"
+.Fc
+.Sh DESCRIPTION
+.Fn PKCS7_final
+reads
+.Fa data
+and puts it into the appropriate content field of
+.Fa p7
+itself or of its appropriate substructure, which can be of type
+.Vt SignedData ,
+.Vt EnvelopedData ,
+.Vt SignedAndEnvelopedData ,
+.Vt DigestedData ,
+or arbitrary data.
+The
+.Xr PKCS7_dataFinal 3
+manual explains which field exactly the data is put into.
+.Pp
+The following
+.Fa flags
+are recognized:
+.Bl -tag -width PKCS7_BINARY
+.It Dv PKCS7_BINARY
+Copy the data verbatim without changing any bytes.
+By default, line endings are replaced with two-byte
+.Qq \er\en
+sequences (ASCII CR+LF).
+If this flag is set,
+.Dv PKCS7_TEXT
+is ignored.
+.It Dv PKCS7_TEXT
+Prepend
+.Qq Content-Type: text/plain
+followed by a blank line to the data.
+This flag is ignored if
+.Dv PKCS7_BINARY
+is also set.
+.El
+.Pp
+If any other bits are set in
+.Fa flags ,
+for example
+.Dv PKCS7_STREAM
+or
+.Dv PKCS7_PARTIAL ,
+they are ignored, allowing to pass the same
+.Fa flags
+argument that was already passed to
+.Xr PKCS7_sign 3
+or
+.Xr PKCS7_encrypt 3 .
+.Pp
+.Fn PKCS7_final
+is most commonly used to finalize a
+.Fa p7
+object returned from a call to
+.Xr PKCS7_sign 3
+that used
+.Fa flags
+including
+.Dv PKCS7_PARTIAL
+or
+.Dv PKCS7_STREAM .
+With these flags,
+.Xr PKCS7_sign 3
+ignores its
+.Fa data
+argument.
+The partial
+.Fa p7
+object returned can then be customized, for example setting up
+multiple signers or non-default digest algorithms with
+.Xr PKCS7_sign_add_signer 3 ,
+before calling
+.Fn PKCS7_final .
+.Pp
+Similarly,
+.Fn PKCS7_final
+can be used to finalize a
+.Fa p7
+object returned from a call to
+.Xr PKCS7_encrypt 3
+that used
+.Fa flags
+including
+.Dv PKCS7_STREAM .
+.Pp
+Since
+.Fn PKCS7_final
+starts by calling
+.Xr PKCS7_dataInit 3
+internally, using it to finalize a
+.Fa p7
+object containing
+.Vt SignedAndEnvelopedData ,
+.Vt DigestedData ,
+or arbitrary data requires the setup described in the
+.Xr PKCS7_dataInit 3
+manual.
+For
+.Vt SignedData
+and
+.Vt EnvelopedData ,
+such manual setup is also feasible, but it is more easily performed with
+.Xr PKCS7_sign 3
+or
+.Xr PKCS7_encrypt 3 ,
+respectively.
+.Pp
+.Fn PKCS7_final
+is only one among several functions that can be used to finalize
+.Fa p7 ;
+alternatives include
+.Xr SMIME_write_PKCS7 3 ,
+.Xr PEM_write_bio_PKCS7_stream 3 ,
+and
+.Xr i2d_PKCS7_bio_stream 3 .
+.Sh RETURN VALUES
+.Fn PKCS7_final
+returns 1 on success or 0 on failure.
+.Pp
+Possible reasons for failure include:
+.Pp
+.Bl -dash -compact -offset 2n -width 1n
+.It
+.Fa p7
+is
+.Dv NULL .
+.It
+The
+.Fa content
+field of
+.Fa p7
+is empty.
+.It
+The
+.Fa contentType
+of
+.Fa p7
+is unsupported.
+.It
+Signing or digesting is requested and
+.Fa p7
+is not configured to store a detached signature, but does not contain
+the required field to store the content either.
+.It
+At least one signer lacks a useable digest algorithm.
+.It
+A cipher is required but none is configured.
+.It
+Any required operation fails, for example signing or digesting.
+.It
+Memory allocation fails.
+.El
+.Pp
+Signers lacking private keys do not cause failure but are silently skipped.
+.Sh SEE ALSO
+.Xr BIO_new 3 ,
+.Xr i2d_PKCS7_bio_stream 3 ,
+.Xr PEM_write_bio_PKCS7_stream 3 ,
+.Xr PKCS7_dataFinal 3 ,
+.Xr PKCS7_dataInit 3 ,
+.Xr PKCS7_encrypt 3 ,
+.Xr PKCS7_new 3 ,
+.Xr PKCS7_sign 3 ,
+.Xr SMIME_write_PKCS7 3
+.Sh HISTORY
+.Fn PKCS7_final
+first appeared in OpenSSL 1.0.0 and has been available since
+.Ox 4.9 .
+.Sh CAVEATS
+This function does not support
+.Vt EncryptedData .
diff --git a/src/lib/libcrypto/man/PKCS7_sign.3 b/src/lib/libcrypto/man/PKCS7_sign.3
index a04e800ca..d5f4c89c6 100644
--- a/src/lib/libcrypto/man/PKCS7_sign.3
+++ b/src/lib/libcrypto/man/PKCS7_sign.3
@@ -1,5 +1,5 @@
-.\" $OpenBSD: PKCS7_sign.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $
-.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
+.\" $OpenBSD: PKCS7_sign.3,v 1.11 2020/06/03 13:41:27 schwarze Exp $
+.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
.\" Copyright (c) 2002, 2003, 2006-2009, 2015 The OpenSSL Project.
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 10 2019 $
+.Dd $Mdocdate: June 3 2020 $
.Dt PKCS7_SIGN 3
.Os
.Sh NAME
@@ -166,11 +166,12 @@ properly finalize the
.Vt PKCS7
structure will give unpredictable results.
.Pp
-Several functions, including
+Several functions including
+.Xr PKCS7_final 3 ,
.Xr SMIME_write_PKCS7 3 ,
-.Xr i2d_PKCS7_bio_stream 3 ,
-and
.Xr PEM_write_bio_PKCS7_stream 3 ,
+and
+.Xr i2d_PKCS7_bio_stream 3
finalize the structure.
Alternatively finalization can be performed by obtaining the streaming
ASN.1
@@ -196,7 +197,7 @@ if the
flag is set.
One or more signers can be added using the function
.Xr PKCS7_sign_add_signer 3 .
-.Fn PKCS7_final
+.Xr PKCS7_final 3
must also be called to finalize the structure if streaming is not
enabled.
Alternative signing digests can also be specified using this method.
@@ -228,6 +229,7 @@ The error can be obtained from
.Xr ERR_get_error 3 .
.Sh SEE ALSO
.Xr PKCS7_encrypt 3 ,
+.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr PKCS7_sign_add_signer 3 ,
.Xr PKCS7_verify 3
diff --git a/src/lib/libcrypto/man/PKCS7_sign_add_signer.3 b/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
index 41d57c2c2..f8024d9b5 100644
--- a/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
+++ b/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
@@ -1,5 +1,5 @@
-.\" $OpenBSD: PKCS7_sign_add_signer.3,v 1.10 2019/06/14 13:59:32 schwarze Exp $
-.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
+.\" $OpenBSD: PKCS7_sign_add_signer.3,v 1.11 2020/06/03 13:41:27 schwarze Exp $
+.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
.\" Copyright (c) 2007, 2008, 2009, 2015 The OpenSSL Project.
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 14 2019 $
+.Dd $Mdocdate: June 3 2020 $
.Dt PKCS7_SIGN_ADD_SIGNER 3
.Os
.Sh NAME
@@ -100,7 +100,7 @@ flag is set, the returned
.Dv PKCS7
structure is not complete and must be
finalized either by streaming (if applicable) or by a call to
-.Fn PKCS7_final .
+.Xr PKCS7_final 3 .
.Pp
The main purpose of this function is to provide finer control over a
PKCS#7 signed data structure where the simpler
@@ -174,6 +174,7 @@ In some cases of failure, the reason can be determined with
.Xr ERR_get_error 3 .
.Sh SEE ALSO
.Xr EVP_DigestInit 3 ,
+.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr PKCS7_sign 3
.Sh HISTORY
diff --git a/src/lib/libcrypto/man/SMIME_write_PKCS7.3 b/src/lib/libcrypto/man/SMIME_write_PKCS7.3
index 8baf6689a..39d8b5d85 100644
--- a/src/lib/libcrypto/man/SMIME_write_PKCS7.3
+++ b/src/lib/libcrypto/man/SMIME_write_PKCS7.3
@@ -1,5 +1,5 @@
-.\" $OpenBSD: SMIME_write_PKCS7.3,v 1.6 2019/06/14 13:59:32 schwarze Exp $
-.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
+.\" $OpenBSD: SMIME_write_PKCS7.3,v 1.7 2020/06/03 13:41:27 schwarze Exp $
+.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
.\" Copyright (c) 2002, 2003, 2006, 2007, 2015 The OpenSSL Project.
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 14 2019 $
+.Dd $Mdocdate: June 3 2020 $
.Dt SMIME_WRITE_PKCS7 3
.Os
.Sh NAME
@@ -132,7 +132,9 @@ otherwise 0 is returned and an error code can be retrieved with
.Xr ERR_get_error 3 .
.Sh SEE ALSO
.Xr i2d_PKCS7_bio_stream 3 ,
+.Xr PEM_write_bio_PKCS7_stream 3 ,
.Xr PEM_write_PKCS7 3 ,
+.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr SMIME_read_PKCS7 3
.Sh HISTORY
diff --git a/src/lib/libcrypto/man/i2d_PKCS7_bio_stream.3 b/src/lib/libcrypto/man/i2d_PKCS7_bio_stream.3
index 463d861be..3d5df72b3 100644
--- a/src/lib/libcrypto/man/i2d_PKCS7_bio_stream.3
+++ b/src/lib/libcrypto/man/i2d_PKCS7_bio_stream.3
@@ -1,5 +1,5 @@
-.\" $OpenBSD: i2d_PKCS7_bio_stream.3,v 1.7 2018/03/23 04:34:23 schwarze Exp $
-.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
+.\" $OpenBSD: i2d_PKCS7_bio_stream.3,v 1.8 2020/06/03 13:41:27 schwarze Exp $
+.\" OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
.\" Copyright (c) 2007, 2008, 2009, 2013 The OpenSSL Project.
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: March 23 2018 $
+.Dd $Mdocdate: June 3 2020 $
.Dt I2D_PKCS7_BIO_STREAM 3
.Os
.Sh NAME
@@ -82,6 +82,7 @@ returns 1 for success or 0 for failure.
.Xr ERR_get_error 3 ,
.Xr PEM_write_bio_PKCS7_stream 3 ,
.Xr PEM_write_PKCS7 3 ,
+.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr SMIME_write_PKCS7 3
.Sh HISTORY
--
2.17.1

View file

@ -0,0 +1,58 @@
From 5029d3d4df84afafd0d2fdb31d907c10b568b7c3 Mon Sep 17 00:00:00 2001
From: tb <>
Date: Tue, 2 Jun 2020 04:50:17 +0000
Subject: [PATCH 04/87] distracting whitespace
---
src/lib/libssl/tls13_server.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/lib/libssl/tls13_server.c b/src/lib/libssl/tls13_server.c
index e9fecdee2..50ae69449 100644
--- a/src/lib/libssl/tls13_server.c
+++ b/src/lib/libssl/tls13_server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_server.c,v 1.55 2020/05/29 18:00:10 jsing Exp $ */
+/* $OpenBSD: tls13_server.c,v 1.56 2020/06/02 04:50:17 tb Exp $ */
/*
* Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
@@ -255,7 +255,7 @@ err:
}
static int
-tls13_server_engage_record_protection(struct tls13_ctx *ctx)
+tls13_server_engage_record_protection(struct tls13_ctx *ctx)
{
struct tls13_secrets *secrets;
struct tls13_secret context;
@@ -469,7 +469,7 @@ tls13_server_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk,
/*
* The digitalSignature bit MUST be set if the Key Usage extension is
* present as per RFC 8446 section 4.4.2.2.
- */
+ */
if ((cpk->x509->ex_flags & EXFLAG_KUSAGE) &&
!(cpk->x509->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE))
goto done;
@@ -483,7 +483,7 @@ tls13_server_check_certificate(struct tls13_ctx *ctx, CERT_PKEY *cpk,
done:
return 1;
}
-
+
static int
tls13_server_select_certificate(struct tls13_ctx *ctx, CERT_PKEY **out_cpk,
const struct ssl_sigalg **out_sigalg)
@@ -586,7 +586,7 @@ tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb)
memset(&sig_cbb, 0, sizeof(sig_cbb));
if ((cpk = ctx->hs->cpk) == NULL)
- goto err;
+ goto err;
if ((sigalg = ctx->hs->sigalg) == NULL)
goto err;
pkey = cpk->privatekey;
--
2.17.1

View file

@ -0,0 +1,378 @@
From 52f72375ae466a3914e02a33dcd4a545ee773d52 Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Thu, 4 Jun 2020 10:24:27 +0000
Subject: [PATCH 05/87] new manual page PKCS7_add_attribute(3); tweaks and OK
tb@
---
src/lib/libcrypto/man/Makefile | 3 +-
src/lib/libcrypto/man/PKCS7_add_attribute.3 | 179 ++++++++++++++++++
src/lib/libcrypto/man/PKCS7_final.3 | 5 +-
src/lib/libcrypto/man/PKCS7_new.3 | 5 +-
src/lib/libcrypto/man/PKCS7_sign.3 | 9 +-
src/lib/libcrypto/man/PKCS7_sign_add_signer.3 | 7 +-
src/lib/libcrypto/man/X509_ATTRIBUTE_new.3 | 5 +-
7 files changed, 201 insertions(+), 12 deletions(-)
create mode 100644 src/lib/libcrypto/man/PKCS7_add_attribute.3
diff --git a/src/lib/libcrypto/man/Makefile b/src/lib/libcrypto/man/Makefile
index 05b992e13..7effea837 100644
--- a/src/lib/libcrypto/man/Makefile
+++ b/src/lib/libcrypto/man/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.165 2020/06/03 13:41:27 schwarze Exp $
+# $OpenBSD: Makefile,v 1.166 2020/06/04 10:24:27 schwarze Exp $
.include <bsd.own.mk>
@@ -214,6 +214,7 @@ MAN= \
PKCS12_parse.3 \
PKCS12_SAFEBAG_new.3 \
PKCS5_PBKDF2_HMAC.3 \
+ PKCS7_add_attribute.3 \
PKCS7_dataFinal.3 \
PKCS7_dataInit.3 \
PKCS7_decrypt.3 \
diff --git a/src/lib/libcrypto/man/PKCS7_add_attribute.3 b/src/lib/libcrypto/man/PKCS7_add_attribute.3
new file mode 100644
index 000000000..09c36a4d5
--- /dev/null
+++ b/src/lib/libcrypto/man/PKCS7_add_attribute.3
@@ -0,0 +1,179 @@
+.\" $OpenBSD: PKCS7_add_attribute.3,v 1.1 2020/06/04 10:24:27 schwarze Exp $
+.\"
+.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and 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.
+.\"
+.Dd $Mdocdate: June 4 2020 $
+.Dt PKCS7_ADD_ATTRIBUTE 3
+.Os
+.Sh NAME
+.Nm PKCS7_add_attribute ,
+.Nm PKCS7_get_attribute ,
+.Nm PKCS7_add_signed_attribute ,
+.Nm PKCS7_get_signed_attribute
+.Nd attributes of SignerInfo objects
+.Sh SYNOPSIS
+.In openssl/pkcs7.h
+.Ft int
+.Fo PKCS7_add_attribute
+.Fa "PKCS7_SIGNER_INFO *si"
+.Fa "int nid"
+.Fa "int attrtype"
+.Fa "void *value"
+.Fc
+.Ft ASN1_TYPE *
+.Fo PKCS7_get_attribute
+.Fa "PKCS7_SIGNER_INFO *si"
+.Fa "int nid"
+.Fc
+.Ft int
+.Fo PKCS7_add_signed_attribute
+.Fa "PKCS7_SIGNER_INFO *si"
+.Fa "int nid"
+.Fa "int attrtype"
+.Fa "void *value"
+.Fc
+.Ft ASN1_TYPE *
+.Fo PKCS7_get_signed_attribute
+.Fa "PKCS7_SIGNER_INFO *si"
+.Fa "int nid"
+.Fc
+.Sh DESCRIPTION
+.Fn PKCS7_add_attribute
+appends a new attribute of type
+.Fa nid
+to the
+.Fa unauthenticatedAttributes
+list of
+.Fa si ,
+and it adds a new ASN.1 ANY object of type
+.Fa attrtype
+with the given
+.Fa value
+to the new attribute.
+Ownership of the
+.Fa value
+is transferred into the new attribute object, so the calling code
+must not
+.Xr free 3
+the
+.Fa value .
+If the list already contains an unauthenticated attribute of type
+.Fa nid
+before the call, the new attribute replaces the old one
+instead of being appended to the end of the list.
+.Pp
+.Fn PKCS7_get_attribute
+retrieves the first ASN.1 ANY member of the attribute of type
+.Fa nid
+from the
+.Fa unauthenticatedAttributes
+list of
+.Fa si .
+.Pp
+The behaviour of
+.Fn PKCS7_add_signed_attribute
+and
+.Fn PKCS7_get_signed_attribute
+is identical except that they operate on the list of
+.Fa authenticatedAttributes .
+.Pp
+The normal way to use
+.Fn PKCS7_add_signed_attribute
+is to first create a
+.Vt SignedInfo
+object with
+.Xr PKCS7_sign 3
+using the
+.Dv PKCS7_PARTIAL
+or
+.Dv PKCS7_STREAM
+flag, retrieve the
+.Vt PKCS7_SIGNER_INFO
+object with the undocumented function
+.Fn PKCS7_get_signer_info
+or add an additional one with
+.Xr PKCS7_sign_add_signer 3 ,
+call
+.Fn PKCS7_add_signed_attribute
+for each desired additional attribute, then do the signing with
+.Xr PKCS7_final 3
+or with another finalizing function.
+.Pp
+For particular types of attributes, undocumented wrapper functions
+.Fn PKCS7_add_attrib_content_type ,
+.Fn PKCS7_add1_attrib_digest ,
+.Fn PKCS7_add0_attrib_signing_time ,
+and
+.Fn PKCS7_add_attrib_smimecap
+exist.
+.Sh RETURN VALUES
+.Fn PKCS7_add_attribute
+and
+.Fn PKCS7_add_signed_attribute
+return 1 on success or 0 on failure.
+The most common reason for failure is lack of memory.
+.Pp
+.Fn PKCS7_get_attribute
+and
+.Fn PKCS7_get_signed_attribute
+return an internal pointer to an ASN.1 ANY object or
+.Dv NULL
+on failure.
+They fail if
+.Fa nid
+is invalid, if the respective list in
+.Fa si
+contains no attribute of the requested type, or if an invalid element
+is found in the list before finding the attribute of the requested type.
+.Sh SEE ALSO
+.Xr ASN1_TYPE_new 3 ,
+.Xr PKCS7_final 3 ,
+.Xr PKCS7_new 3 ,
+.Xr PKCS7_sign 3 ,
+.Xr PKCS7_sign_add_signer 3 ,
+.Xr STACK_OF 3 ,
+.Xr X509_ATTRIBUTE_new 3
+.Sh STANDARDS
+RFC 2315: PKCS #7: Cryptographic Message Syntax Version 1.5,
+section 9.2: SignerInfo type
+.Sh HISTORY
+These functions first appeared in OpenSSL 0.9.1
+and have been available since
+.Ox 2.6 .
+.Sh BUGS
+Adding an attribute with an invalid
+.Fa nid
+ought to fail, but it actually succeeds
+setting the type of the new attribute to
+.Dv NULL .
+Subsequent attempts to retrieve attributes
+may cause the program to crash due to
+.Dv NULL
+pointer access.
+.Pp
+A function to remove individual attributes from these lists
+does not appear to exist.
+A program desiring to do that might have to manually iterate the fields
+.Fa auth_attr
+and
+.Fa unauth_attr
+of
+.Fa si ,
+which are both of type
+.Vt STACK_OF(X509_ATTRIBUTE) ,
+using the facilities described in
+.Xr STACK_OF 3
+and
+.Xr OPENSSL_sk_new 3 .
diff --git a/src/lib/libcrypto/man/PKCS7_final.3 b/src/lib/libcrypto/man/PKCS7_final.3
index 593483bb6..7c9e51521 100644
--- a/src/lib/libcrypto/man/PKCS7_final.3
+++ b/src/lib/libcrypto/man/PKCS7_final.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_final.3,v 1.1 2020/06/03 13:41:27 schwarze Exp $
+.\" $OpenBSD: PKCS7_final.3,v 1.2 2020/06/04 10:24:27 schwarze Exp $
.\"
.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 3 2020 $
+.Dd $Mdocdate: June 4 2020 $
.Dt PKCS7_FINAL 3
.Os
.Sh NAME
@@ -186,6 +186,7 @@ Signers lacking private keys do not cause failure but are silently skipped.
.Xr BIO_new 3 ,
.Xr i2d_PKCS7_bio_stream 3 ,
.Xr PEM_write_bio_PKCS7_stream 3 ,
+.Xr PKCS7_add_attribute 3 ,
.Xr PKCS7_dataFinal 3 ,
.Xr PKCS7_dataInit 3 ,
.Xr PKCS7_encrypt 3 ,
diff --git a/src/lib/libcrypto/man/PKCS7_new.3 b/src/lib/libcrypto/man/PKCS7_new.3
index 4abe3698e..c5eebe96d 100644
--- a/src/lib/libcrypto/man/PKCS7_new.3
+++ b/src/lib/libcrypto/man/PKCS7_new.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_new.3,v 1.10 2020/05/27 12:00:44 schwarze Exp $
+.\" $OpenBSD: PKCS7_new.3,v 1.11 2020/06/04 10:24:27 schwarze Exp $
.\"
.\" Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 27 2020 $
+.Dd $Mdocdate: June 4 2020 $
.Dt PKCS7_NEW 3
.Os
.Sh NAME
@@ -246,6 +246,7 @@ frees
.Xr i2d_PKCS7_bio_stream 3 ,
.Xr PEM_read_PKCS7 3 ,
.Xr PEM_write_bio_PKCS7_stream 3 ,
+.Xr PKCS7_add_attribute 3 ,
.Xr PKCS7_dataFinal 3 ,
.Xr PKCS7_dataInit 3 ,
.Xr PKCS7_decrypt 3 ,
diff --git a/src/lib/libcrypto/man/PKCS7_sign.3 b/src/lib/libcrypto/man/PKCS7_sign.3
index d5f4c89c6..c9b13680c 100644
--- a/src/lib/libcrypto/man/PKCS7_sign.3
+++ b/src/lib/libcrypto/man/PKCS7_sign.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_sign.3,v 1.11 2020/06/03 13:41:27 schwarze Exp $
+.\" $OpenBSD: PKCS7_sign.3,v 1.12 2020/06/04 10:24:27 schwarze Exp $
.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 3 2020 $
+.Dd $Mdocdate: June 4 2020 $
.Dt PKCS7_SIGN 3
.Os
.Sh NAME
@@ -196,7 +196,9 @@ if the
.Dv PKCS7_PARTIAL
flag is set.
One or more signers can be added using the function
-.Xr PKCS7_sign_add_signer 3 .
+.Xr PKCS7_sign_add_signer 3
+and attributes can be added using the functions described in
+.Xr PKCS7_add_attribute 3 .
.Xr PKCS7_final 3
must also be called to finalize the structure if streaming is not
enabled.
@@ -228,6 +230,7 @@ if an error occurred.
The error can be obtained from
.Xr ERR_get_error 3 .
.Sh SEE ALSO
+.Xr PKCS7_add_attribute 3 ,
.Xr PKCS7_encrypt 3 ,
.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
diff --git a/src/lib/libcrypto/man/PKCS7_sign_add_signer.3 b/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
index f8024d9b5..28d327fef 100644
--- a/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
+++ b/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_sign_add_signer.3,v 1.11 2020/06/03 13:41:27 schwarze Exp $
+.\" $OpenBSD: PKCS7_sign_add_signer.3,v 1.12 2020/06/04 10:24:27 schwarze Exp $
.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 3 2020 $
+.Dd $Mdocdate: June 4 2020 $
.Dt PKCS7_SIGN_ADD_SIGNER 3
.Os
.Sh NAME
@@ -162,6 +162,8 @@ If any of these algorithms is disabled, then it will not be included.
returns an internal pointer to the
.Vt PKCS7_SIGNER_INFO
structure just added, which can be used to set additional attributes
+with the functions described in
+.Xr PKCS7_add_attribute 3
before it is finalized.
.Sh RETURN VALUES
.Fn PKCS7_sign_add_signer
@@ -174,6 +176,7 @@ In some cases of failure, the reason can be determined with
.Xr ERR_get_error 3 .
.Sh SEE ALSO
.Xr EVP_DigestInit 3 ,
+.Xr PKCS7_add_attribute 3 ,
.Xr PKCS7_final 3 ,
.Xr PKCS7_new 3 ,
.Xr PKCS7_sign 3
diff --git a/src/lib/libcrypto/man/X509_ATTRIBUTE_new.3 b/src/lib/libcrypto/man/X509_ATTRIBUTE_new.3
index b5c78ee8d..66779d637 100644
--- a/src/lib/libcrypto/man/X509_ATTRIBUTE_new.3
+++ b/src/lib/libcrypto/man/X509_ATTRIBUTE_new.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: X509_ATTRIBUTE_new.3,v 1.7 2019/06/06 01:06:59 schwarze Exp $
+.\" $OpenBSD: X509_ATTRIBUTE_new.3,v 1.8 2020/06/04 10:24:27 schwarze Exp $
.\"
.\" Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 6 2019 $
+.Dd $Mdocdate: June 4 2020 $
.Dt X509_ATTRIBUTE_NEW 3
.Os
.Sh NAME
@@ -65,6 +65,7 @@ if an error occurs.
.Sh SEE ALSO
.Xr d2i_X509_ATTRIBUTE 3 ,
.Xr PKCS12_SAFEBAG_new 3 ,
+.Xr PKCS7_add_attribute 3 ,
.Xr PKCS8_PRIV_KEY_INFO_new 3 ,
.Xr X509_EXTENSION_new 3 ,
.Xr X509_new 3 ,
--
2.17.1

View file

@ -0,0 +1,41 @@
From dd750e94b69c061918acd26fe950f1ccbeb7b200 Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Thu, 4 Jun 2020 18:06:43 +0000
Subject: [PATCH 06/87] mention that TLS_method(3) also supports TLSv1.3; tb@
OKed this part of a larger diff from inoguchi@
---
src/lib/libssl/man/SSL_CTX_new.3 | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/lib/libssl/man/SSL_CTX_new.3 b/src/lib/libssl/man/SSL_CTX_new.3
index 35fe702fb..13b370024 100644
--- a/src/lib/libssl/man/SSL_CTX_new.3
+++ b/src/lib/libssl/man/SSL_CTX_new.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: SSL_CTX_new.3,v 1.11 2019/03/18 06:23:38 schwarze Exp $
+.\" $OpenBSD: SSL_CTX_new.3,v 1.12 2020/06/04 18:06:43 schwarze Exp $
.\" full merge up to: OpenSSL 21cd6e00 Oct 21 14:40:15 2015 +0100
.\" selective merge up to: OpenSSL 1212818e Sep 11 13:22:14 2018 +0100
.\"
@@ -50,7 +50,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: March 18 2019 $
+.Dd $Mdocdate: June 4 2020 $
.Dt SSL_CTX_NEW 3
.Os
.Sh NAME
@@ -170,7 +170,7 @@ can be of the following types:
These are the general-purpose version-flexible SSL/TLS methods.
The actual protocol version used will be negotiated to the highest
version mutually supported by the client and the server.
-The supported protocols are TLSv1, TLSv1.1 and TLSv1.2.
+The supported protocols are TLSv1, TLSv1.1, TLSv1.2, and TLSv1.3.
Applications should use these methods and avoid the version-specific
methods described below.
.It Xo
--
2.17.1

View file

@ -0,0 +1,58 @@
From c3d4e71233267840d28afd8f8e5dfe96934517c1 Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Thu, 4 Jun 2020 20:06:04 +0000
Subject: [PATCH 07/87] minor polishing: * below SEE ALSO, point to the most
similar function that is not deprecated * add a comment saying why
ERR_load_ERR_strings() is intentionally undocumented * update the comment
specifying the merge status
---
src/lib/libcrypto/man/ERR_load_crypto_strings.3 | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/lib/libcrypto/man/ERR_load_crypto_strings.3 b/src/lib/libcrypto/man/ERR_load_crypto_strings.3
index e3d60527d..4ad12659a 100644
--- a/src/lib/libcrypto/man/ERR_load_crypto_strings.3
+++ b/src/lib/libcrypto/man/ERR_load_crypto_strings.3
@@ -1,5 +1,6 @@
-.\" $OpenBSD: ERR_load_crypto_strings.3,v 1.8 2019/06/14 13:41:31 schwarze Exp $
-.\" OpenSSL a528d4f0 Oct 27 13:40:11 2015 -0400
+.\" $OpenBSD: ERR_load_crypto_strings.3,v 1.9 2020/06/04 20:06:04 schwarze Exp $
+.\" full merge up to: OpenSSL f672aee4 Feb 9 11:52:40 2016 -0500
+.\" selective merge up to: OpenSSL b3696a55 Sep 2 09:35:50 2017 -0400
.\"
.\" This file is a derived work.
.\" The changes are covered by the following Copyright and license:
@@ -65,7 +66,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 14 2019 $
+.Dd $Mdocdate: June 4 2020 $
.Dt ERR_LOAD_CRYPTO_STRINGS 3
.Os
.Sh NAME
@@ -73,6 +74,10 @@
.Nm ERR_free_strings ,
.Nm SSL_load_error_strings
.Nd load and free OpenSSL error strings
+.\" The function ERR_load_ERR_strings() is intentionally undocumented
+.\" because it is merely a subroutine of ERR_load_crypto_strings(3)
+.\" and should not have been made a part of the API.
+.\" The same applies to the other ERR_load_*_strings() functions.
.Sh SYNOPSIS
.In openssl/err.h
.Ft void
@@ -102,7 +107,8 @@ If the error strings were already loaded before, no action occurs.
frees all previously loaded error strings.
.Sh SEE ALSO
.Xr ERR 3 ,
-.Xr ERR_error_string 3
+.Xr ERR_error_string 3 ,
+.Xr OPENSSL_config 3
.Sh HISTORY
.Fn ERR_load_crypto_strings
and
--
2.17.1

View file

@ -0,0 +1,90 @@
From 84b027f3d640592489672ef62ee8f0032ebc4ce6 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 15:51:49 +0000
Subject: [PATCH 08/87] Apply some style(9).
---
src/lib/libcrypto/gost/gost_err.c | 64 +++++++++++++++----------------
1 file changed, 30 insertions(+), 34 deletions(-)
diff --git a/src/lib/libcrypto/gost/gost_err.c b/src/lib/libcrypto/gost/gost_err.c
index 3bf60ff06..e7111dd34 100644
--- a/src/lib/libcrypto/gost/gost_err.c
+++ b/src/lib/libcrypto/gost/gost_err.c
@@ -73,43 +73,39 @@ static ERR_STRING_DATA GOST_str_functs[]= {
{0, NULL}
};
-static ERR_STRING_DATA GOST_str_reasons[]=
- {
-{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"},
-{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"},
-{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"},
-{ERR_REASON(GOST_R_CTRL_CALL_FAILED) ,"ctrl call failed"},
-{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"},
-{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"},
-{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
-{ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY),"incompatible peer key"},
-{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
-{ERR_REASON(GOST_R_INVALID_IV_LENGTH) ,"invalid iv length"},
-{ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"},
-{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"},
-{ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"},
-{ERR_REASON(GOST_R_MAC_KEY_NOT_SET) ,"mac key not set"},
-{ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"},
-{ERR_REASON(GOST_R_NO_PEER_KEY) ,"no peer key"},
-{ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"},
-{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"},
-{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"},
-{ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"},
-{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
-{ERR_REASON(GOST_R_UKM_NOT_SET) ,"ukm not set"},
-{0,NULL}
- };
-
+static ERR_STRING_DATA GOST_str_reasons[] = {
+ {ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"},
+ {ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"},
+ {ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"},
+ {ERR_REASON(GOST_R_CTRL_CALL_FAILED) ,"ctrl call failed"},
+ {ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"},
+ {ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"},
+ {ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
+ {ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY),"incompatible peer key"},
+ {ERR_REASON(GOST_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
+ {ERR_REASON(GOST_R_INVALID_IV_LENGTH) ,"invalid iv length"},
+ {ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"},
+ {ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"},
+ {ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"},
+ {ERR_REASON(GOST_R_MAC_KEY_NOT_SET) ,"mac key not set"},
+ {ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"},
+ {ERR_REASON(GOST_R_NO_PEER_KEY) ,"no peer key"},
+ {ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"},
+ {ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"},
+ {ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"},
+ {ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"},
+ {ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
+ {ERR_REASON(GOST_R_UKM_NOT_SET) ,"ukm not set"},
+ {0, NULL}
+};
#endif
-void ERR_load_GOST_strings(void)
- {
+void
+ERR_load_GOST_strings(void) {
#ifndef OPENSSL_NO_ERR
-
- if (ERR_func_error_string(GOST_str_functs[0].error) == NULL)
- {
+ if (ERR_func_error_string(GOST_str_functs[0].error) == NULL) {
ERR_load_strings(0,GOST_str_functs);
ERR_load_strings(0,GOST_str_reasons);
- }
-#endif
}
+#endif
+}
--
2.17.1

View file

@ -0,0 +1,300 @@
From d0368ed4943958dfb98e6fc5c1a005ea9bddc49c Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 17:12:09 +0000
Subject: [PATCH 09/87] Add support for additional GOST curves.
These GOST curves are defined in RFC 7836 and draft-deremin-rfc4491-bis.
Add aliases for 256-bit GOST curves (see
draft-smyshlyaev-tls12-gost-suites) and rename the 512-bit curve ids to
follow names defined in tc26 OID registry.
Diff from Dmitry Baryshkov <dbaryshkov@gmail.com>
Sponsored by ROSA Linux.
ok inoguchi@
---
src/lib/libcrypto/ec/ec_curve.c | 168 +++++++++++++++++++-
src/lib/libcrypto/gost/gostr341001_params.c | 6 +-
src/lib/libcrypto/objects/obj_mac.num | 10 +-
src/lib/libcrypto/objects/objects.txt | 10 +-
4 files changed, 182 insertions(+), 12 deletions(-)
diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c
index e075b1ed3..84a565d43 100644
--- a/src/lib/libcrypto/ec/ec_curve.c
+++ b/src/lib/libcrypto/ec/ec_curve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ec_curve.c,v 1.19 2018/07/15 16:27:39 tb Exp $ */
+/* $OpenBSD: ec_curve.c,v 1.20 2020/06/05 17:12:09 jsing Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
@@ -2900,11 +2900,105 @@ 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, 0x05, 0x7c, 0xc8, 0x25, 0xf9, 0x10, 0x93, 0xa6, 0x8c,
+ 0xd7, 0x62, 0xfd, 0x60, 0x61, 0x12, 0x62, 0xcd, 0x83, 0x8d,
+ 0xc6, 0xb6, 0x0a, 0xa7, 0xee, 0xe8, 0x04, 0xe2, 0x8b, 0xc8,
+ 0x49, 0x97, 0x7f, 0xac, 0x33, 0xb4, 0xb5, 0x30, 0xf1, 0xb1,
+ 0x20, 0x24, 0x8a, 0x9a,
+ 0x2b, 0xb3, 0x12, 0xa4, 0x3b, 0xd2, 0xce, 0x6e, 0x0d, 0x02, /* y */
+ 0x06, 0x13, 0xc8, 0x57, 0xac, 0xdd, 0xcf, 0xbf, 0x06, 0x1e,
+ 0x91, 0xe5, 0xf2, 0xc3, 0xf3, 0x24, 0x47, 0xc2, 0x59, 0xf3,
+ 0x9b, 0x2c, 0x83, 0xab, 0x15, 0x6d, 0x77, 0xf1, 0x49, 0x6b,
+ 0xf7, 0xeb, 0x33, 0x51, 0xe1, 0xee, 0x4e, 0x43, 0xdc, 0x1a,
+ 0x18, 0xb9, 0x1b, 0x24, 0x64, 0x0b, 0x6d, 0xbb, 0x92, 0xcb,
+ 0x1a, 0xdd, 0x37, 0x1e,
+ 0x45, 0x31, 0xac, 0xd1, 0xfe, 0x00, 0x23, 0xc7, 0x55, 0x0d, /* order */
+ 0x26, 0x7b, 0x6b, 0x2f, 0xee, 0x80, 0x92, 0x2b, 0x14, 0xb2,
+ 0xff, 0xb9, 0x0f, 0x04, 0xd4, 0xeb, 0x7c, 0x09, 0xb5, 0xd2,
+ 0xd1, 0x5d, 0xa8, 0x2f, 0x2d, 0x7e, 0xcb, 0x1d, 0xba, 0xc7,
+ 0x19, 0x90, 0x5c, 0x5e, 0xec, 0xc4, 0x23, 0xf1, 0xd8, 0x6e,
+ 0x25, 0xed, 0xbe, 0x23, 0xc5, 0x95, 0xd6, 0x44, 0xaa, 0xf1,
+ 0x87, 0xe6, 0xe6, 0xdf,
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 64 * 6];
+}
+ _EC_GOST_2012_512_TC26_A = {
{
NID_X9_62_prime_field, 0, 64, 1
},
@@ -2958,7 +3052,7 @@ static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 64 * 6];
}
- _EC_GOST_2012_TC26_B = {
+ _EC_GOST_2012_512_TC26_B = {
{
NID_X9_62_prime_field, 0, 64, 1
},
@@ -3008,6 +3102,64 @@ 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 + 64 * 6];
+}
+ _EC_GOST_2012_512_TC26_C = {
+ {
+ NID_X9_62_prime_field, 0, 64, 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,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xfd, 0xc7,
+ 0xdc, 0x92, 0x03, 0xe5, 0x14, 0xa7, 0x21, 0x87, 0x54, 0x85, /* a */
+ 0xa5, 0x29, 0xd2, 0xc7, 0x22, 0xfb, 0x18, 0x7b, 0xc8, 0x98,
+ 0x0e, 0xb8, 0x66, 0x64, 0x4d, 0xe4, 0x1c, 0x68, 0xe1, 0x43,
+ 0x06, 0x45, 0x46, 0xe8, 0x61, 0xc0, 0xe2, 0xc9, 0xed, 0xd9,
+ 0x2a, 0xde, 0x71, 0xf4, 0x6f, 0xcf, 0x50, 0xff, 0x2a, 0xd9,
+ 0x7f, 0x95, 0x1f, 0xda, 0x9f, 0x2a, 0x2e, 0xb6, 0x54, 0x6f,
+ 0x39, 0x68, 0x9b, 0xd3,
+ 0xb4, 0xc4, 0xee, 0x28, 0xce, 0xbc, 0x6c, 0x2c, 0x8a, 0xc1, /* b */
+ 0x29, 0x52, 0xcf, 0x37, 0xf1, 0x6a, 0xc7, 0xef, 0xb6, 0xa9,
+ 0xf6, 0x9f, 0x4b, 0x57, 0xff, 0xda, 0x2e, 0x4f, 0x0d, 0xe5,
+ 0xad, 0xe0, 0x38, 0xcb, 0xc2, 0xff, 0xf7, 0x19, 0xd2, 0xc1,
+ 0x8d, 0xe0, 0x28, 0x4b, 0x8b, 0xfe, 0xf3, 0xb5, 0x2b, 0x8c,
+ 0xc7, 0xa5, 0xf5, 0xbf, 0x0a, 0x3c, 0x8d, 0x23, 0x19, 0xa5,
+ 0x31, 0x25, 0x57, 0xe1,
+ 0xe2, 0xe3, 0x1e, 0xdf, 0xc2, 0x3d, 0xe7, 0xbd, 0xeb, 0xe2, /* x */
+ 0x41, 0xce, 0x59, 0x3e, 0xf5, 0xde, 0x22, 0x95, 0xb7, 0xa9,
+ 0xcb, 0xae, 0xf0, 0x21, 0xd3, 0x85, 0xf7, 0x07, 0x4c, 0xea,
+ 0x04, 0x3a, 0xa2, 0x72, 0x72, 0xa7, 0xae, 0x60, 0x2b, 0xf2,
+ 0xa7, 0xb9, 0x03, 0x3d, 0xb9, 0xed, 0x36, 0x10, 0xc6, 0xfb,
+ 0x85, 0x48, 0x7e, 0xae, 0x97, 0xaa, 0xc5, 0xbc, 0x79, 0x28,
+ 0xc1, 0x95, 0x01, 0x48,
+ 0xf5, 0xce, 0x40, 0xd9, 0x5b, 0x5e, 0xb8, 0x99, 0xab, 0xbc, /* y */
+ 0xcf, 0xf5, 0x91, 0x1c, 0xb8, 0x57, 0x79, 0x39, 0x80, 0x4d,
+ 0x65, 0x27, 0x37, 0x8b, 0x8c, 0x10, 0x8c, 0x3d, 0x20, 0x90,
+ 0xff, 0x9b, 0xe1, 0x8e, 0x2d, 0x33, 0xe3, 0x02, 0x1e, 0xd2,
+ 0xef, 0x32, 0xd8, 0x58, 0x22, 0x42, 0x3b, 0x63, 0x04, 0xf7,
+ 0x26, 0xaa, 0x85, 0x4b, 0xae, 0x07, 0xd0, 0x39, 0x6e, 0x9a,
+ 0x9a, 0xdd, 0xc4, 0x0f,
+ 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* order */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xc9, 0x8c, 0xdb, 0xa4, 0x65, 0x06, 0xab, 0x00,
+ 0x4c, 0x33, 0xa9, 0xff, 0x51, 0x47, 0x50, 0x2c, 0xc8, 0xed,
+ 0xa9, 0xe7, 0xa7, 0x69, 0xa1, 0x26, 0x94, 0x62, 0x3c, 0xef,
+ 0x47, 0xf0, 0x23, 0xed,
+ }
+};
+
#endif
typedef struct _ec_list_element_st {
@@ -3147,8 +3299,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"},
- {NID_id_tc26_gost_3410_2012_512_paramSetA, &_EC_GOST_2012_TC26_A.h, 0, "GOST R 34.10-2012 TC26-A"},
- {NID_id_tc26_gost_3410_2012_512_paramSetB, &_EC_GOST_2012_TC26_B.h, 0, "GOST R 34.10-2012 TC26-B"},
+ {NID_id_tc26_gost_3410_12_256_paramSetA, &_EC_GOST_2012_256_TC26_A.h, 0, "GOST R 34.10-2012 256 TC26-A"},
+ {NID_id_tc26_gost_3410_12_256_paramSetB, &_EC_GOST_2001_CryptoPro_A.h, 0, "GOST R 34.10-2012 256 TC26-B"},
+ {NID_id_tc26_gost_3410_12_256_paramSetC, &_EC_GOST_2001_CryptoPro_B.h, 0, "GOST R 34.10-2012 256 TC26-C"},
+ {NID_id_tc26_gost_3410_12_256_paramSetD, &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2012 256 TC26-D"},
+ {NID_id_tc26_gost_3410_12_512_paramSetTest, &_EC_GOST_2012_512_Test.h, 0, "GOST R 34.10-2012 512 Test Curve"},
+ {NID_id_tc26_gost_3410_12_512_paramSetA, &_EC_GOST_2012_512_TC26_A.h, 0, "GOST R 34.10-2012 512 TC26-A"},
+ {NID_id_tc26_gost_3410_12_512_paramSetB, &_EC_GOST_2012_512_TC26_B.h, 0, "GOST R 34.10-2012 512 TC26-B"},
+ {NID_id_tc26_gost_3410_12_512_paramSetC, &_EC_GOST_2012_512_TC26_C.h, 0, "GOST R 34.10-2012 512 TC26-C"},
#endif
};
diff --git a/src/lib/libcrypto/gost/gostr341001_params.c b/src/lib/libcrypto/gost/gostr341001_params.c
index 6500c30f3..282a21041 100644
--- a/src/lib/libcrypto/gost/gostr341001_params.c
+++ b/src/lib/libcrypto/gost/gostr341001_params.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gostr341001_params.c,v 1.3 2015/07/20 22:42:56 bcook Exp $ */
+/* $OpenBSD: gostr341001_params.c,v 1.4 2020/06/05 17:12:09 jsing Exp $ */
/*
* Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
* Copyright (c) 2005-2006 Cryptocom LTD
@@ -98,8 +98,8 @@ static const GostR3410_params GostR3410_256_params[] = {
};
static const GostR3410_params GostR3410_512_params[] = {
- { "A", NID_id_tc26_gost_3410_2012_512_paramSetA },
- { "B", NID_id_tc26_gost_3410_2012_512_paramSetB },
+ { "A", NID_id_tc26_gost_3410_12_512_paramSetA },
+ { "B", NID_id_tc26_gost_3410_12_512_paramSetB },
{ NULL, NID_undef },
};
diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num
index 8405ba5e3..3f0b5666f 100644
--- a/src/lib/libcrypto/objects/obj_mac.num
+++ b/src/lib/libcrypto/objects/obj_mac.num
@@ -940,8 +940,8 @@ gost89_cbc 939
tc26 940
id_tc26_gost3411_2012_256 941
id_tc26_gost3411_2012_512 942
-id_tc26_gost_3410_2012_512_paramSetA 943
-id_tc26_gost_3410_2012_512_paramSetB 944
+id_tc26_gost_3410_12_512_paramSetA 943
+id_tc26_gost_3410_12_512_paramSetB 944
id_tc26_gost_28147_param_Z 945
id_tc26_gost3410_2012_256 946
id_tc26_gost3410_2012_512 947
@@ -990,3 +990,9 @@ dhSinglePass_cofactorDH_sha512kdf_scheme 989
dh_std_kdf 990
dh_cofactor_kdf 991
pSpecified 992
+id_tc26_gost_3410_12_256_paramSetA 993
+id_tc26_gost_3410_12_256_paramSetB 994
+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
diff --git a/src/lib/libcrypto/objects/objects.txt b/src/lib/libcrypto/objects/objects.txt
index ea7700724..42f31c3cb 100644
--- a/src/lib/libcrypto/objects/objects.txt
+++ b/src/lib/libcrypto/objects/objects.txt
@@ -1372,8 +1372,14 @@ 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 2 1 2 1 : id-tc26-gost-3410-2012-512-paramSetA
-tc26 2 1 2 2 : id-tc26-gost-3410-2012-512-paramSetB
+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
+tc26 2 1 1 4 : id-tc26-gost-3410-12-256-paramSetD : GOST R 34.10-2012 (256 bit) ParamSet D
+tc26 2 1 2 0 : id-tc26-gost-3410-12-512-paramSetTest : GOST R 34.10-2012 (512 bit) testing parameter set
+tc26 2 1 2 1 : id-tc26-gost-3410-12-512-paramSetA : GOST R 34.10-2012 (512 bit) ParamSet A
+tc26 2 1 2 2 : id-tc26-gost-3410-12-512-paramSetB : GOST R 34.10-2012 (512 bit) ParamSet B
+tc26 2 1 2 3 : id-tc26-gost-3410-12-512-paramSetC : GOST R 34.10-2012 (512 bit) ParamSet C
tc26 2 5 1 1 : id-tc26-gost-28147-param-Z
tc26 1 1 1 : id-tc26-gost3410-2012-256 : GOST R 34.10-2012 (256 bit)
tc26 1 1 2 : id-tc26-gost3410-2012-512 : GOST R 34.10-2012 (512 bit)
--
2.17.1

View file

@ -0,0 +1,85 @@
From 8684eee04716891b26d77093c53c3792bc40580b Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 17:17:22 +0000
Subject: [PATCH 10/87] Add a few more errors to help debugging.
Diff from Dmitry Baryshkov <dbaryshkov@gmail.com>
Sponsored by ROSA Linux.
ok inoguchi@ tb@
---
src/lib/libcrypto/gost/gostr341001_ameth.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 16295996d..27a95f206 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gostr341001_ameth.c,v 1.15 2018/08/24 20:22:15 tb Exp $ */
+/* $OpenBSD: gostr341001_ameth.c,v 1.16 2020/06/05 17:17:22 jsing Exp $ */
/*
* Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
* Copyright (c) 2005-2006 Cryptocom LTD
@@ -96,15 +96,19 @@ decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len)
ec = pkey->pkey.gost;
if (ec == NULL) {
ec = GOST_KEY_new();
- if (ec == NULL)
+ if (ec == NULL) {
+ GOSTerror(ERR_R_MALLOC_FAILURE);
return 0;
+ }
if (EVP_PKEY_assign_GOST(pkey, ec) == 0)
return 0;
}
group = EC_GROUP_new_by_curve_name(param_nid);
- if (group == NULL)
+ if (group == NULL) {
+ GOSTerror(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
return 0;
+ }
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
if (GOST_KEY_set_group(ec, group) == 0) {
EC_GROUP_free(group);
@@ -207,8 +211,10 @@ pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
return 0;
}
p = pval->data;
- if (decode_gost01_algor_params(pk, &p, pval->length) == 0)
+ if (decode_gost01_algor_params(pk, &p, pval->length) == 0) {
+ GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
return 0;
+ }
octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
if (octet == NULL) {
@@ -407,8 +413,10 @@ priv_decode_gost01(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf)
int ptype = V_ASN1_UNDEF;
ASN1_STRING *pval = NULL;
- if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0)
+ if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0) {
+ GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
return 0;
+ }
(void)EVP_PKEY_assign_GOST(pk, NULL);
X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg);
if (ptype != V_ASN1_SEQUENCE) {
@@ -416,8 +424,10 @@ priv_decode_gost01(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf)
return 0;
}
p = pval->data;
- if (decode_gost01_algor_params(pk, &p, pval->length) == 0)
+ if (decode_gost01_algor_params(pk, &p, pval->length) == 0) {
+ GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
return 0;
+ }
p = pkey_buf;
if (V_ASN1_OCTET_STRING == *p) {
/* New format - Little endian octet string */
--
2.17.1

View file

@ -0,0 +1,42 @@
From 6971f6b41730ba03beb943114a44cc6898b9b663 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 17:28:56 +0000
Subject: [PATCH 11/87] Add OIDs for HMAC using Streebog (GOST R 34.11-2012)
hash function.
Diff from Dmitry Baryshkov <dbaryshkov@gmail.com>
Sponsored by ROSA Linux
ok inoguchi@ tb@
---
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 3f0b5666f..ba75ec246 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 42f31c3cb..8e533530f 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.17.1

View file

@ -0,0 +1,36 @@
From 059e028bf15f9a770c67e4b167b15c3883f540ab Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 17:30:41 +0000
Subject: [PATCH 12/87] Allow GOST R 34.11-2012 in PBE/PBKDF2/PKCS#5.
Diff from Dmitry Baryshkov <dbaryshkov@gmail.com>
Sponsored by ROSA Linux
ok inoguchi@ tb@
---
src/lib/libcrypto/evp/evp_pbe.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/lib/libcrypto/evp/evp_pbe.c b/src/lib/libcrypto/evp/evp_pbe.c
index de08c8d78..65e9e45ea 100644
--- a/src/lib/libcrypto/evp/evp_pbe.c
+++ b/src/lib/libcrypto/evp/evp_pbe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_pbe.c,v 1.25 2017/01/29 17:49:23 beck Exp $ */
+/* $OpenBSD: evp_pbe.c,v 1.26 2020/06/05 17:30:41 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -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.17.1

View file

@ -0,0 +1,72 @@
From bea1abe78c72962af15bd0868e9dd2fcffd9ddf9 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 17:53:26 +0000
Subject: [PATCH 13/87] Enable GOST_SIG_FORMAT_RS_LE when verifying certificate
signatures.
GOST cipher suites requires that CertVerify signatures be generated in a
special way (see ssl3_send_client_kex_gost(), ssl3_get_cert_verify()).
However, the GOST_SIG_FORMAT_RS_LE flag was not passed in case of TLS 1.2
connections (because they use different code path). Set this flag on
GOST PKEYs.
Diff from Dmitry Baryshkov <dbaryshkov@gmail.com>
Sponsored by ROSA Linux
ok inoguchi@ tb@
---
src/lib/libssl/ssl_clnt.c | 8 +++++++-
src/lib/libssl/ssl_srvr.c | 9 ++++++++-
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c
index 4d003466c..0a1b6ea24 100644
--- a/src/lib/libssl/ssl_clnt.c
+++ b/src/lib/libssl/ssl_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_clnt.c,v 1.68 2020/05/31 16:36:35 jsing Exp $ */
+/* $OpenBSD: ssl_clnt.c,v 1.69 2020/06/05 17:53:26 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -2341,6 +2341,12 @@ ssl3_send_client_verify_sigalgs(SSL *s, CBB *cert_verify)
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
+ if (sigalg->key_type == EVP_PKEY_GOSTR01 &&
+ 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 fac24f4d0..69e547cbe 100644
--- a/src/lib/libssl/ssl_srvr.c
+++ b/src/lib/libssl/ssl_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_srvr.c,v 1.77 2020/05/31 16:36:35 jsing Exp $ */
+/* $OpenBSD: ssl_srvr.c,v 1.79 2020/06/05 17:53:26 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -2187,6 +2187,13 @@ ssl3_get_cert_verify(SSL *s)
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
+ if (sigalg->key_type == EVP_PKEY_GOSTR01 &&
+ 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(&mctx, hdata, hdatalen)) {
SSLerror(s, ERR_R_EVP_LIB);
al = SSL_AD_INTERNAL_ERROR;
--
2.17.1

View file

@ -0,0 +1,40 @@
From 72d5aaa54573c61341b1830ff3a377cf332267ea Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 17:55:24 +0000
Subject: [PATCH 14/87] Handle GOST in ssl_cert_dup().
Add missing case entry for SSL_PKEY_GOST01.
Diff from Dmitry Baryshkov <dbaryshkov@gmail.com>
Sponsored by ROSA Linux
ok inoguchi@ tb@
---
src/lib/libssl/ssl_cert.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/lib/libssl/ssl_cert.c b/src/lib/libssl/ssl_cert.c
index 3567b7b42..43e833196 100644
--- a/src/lib/libssl/ssl_cert.c
+++ b/src/lib/libssl/ssl_cert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_cert.c,v 1.77 2020/05/19 16:35:20 jsing Exp $ */
+/* $OpenBSD: ssl_cert.c,v 1.78 2020/06/05 17:55:24 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -248,6 +248,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.17.1

View file

@ -0,0 +1,40 @@
From e0892f5cadc07677b7b04f03c62f184ae0ea4fa5 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 17:58:32 +0000
Subject: [PATCH 15/87] Stop sending GOST R 34.10-94 as a CertificateType.
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.
Diff from Dmitry Baryshkov <dbaryshkov@gmail.com>
Sponsored by ROSA Linux
ok inoguchi@ tb@
---
src/lib/libssl/s3_lib.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index afc798bed..f98ec3e09 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.193 2020/05/10 14:17:47 jsing Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.194 2020/06/05 17:58:32 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -2547,8 +2547,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))
--
2.17.1

View file

@ -0,0 +1,96 @@
From 8559d74b6337caf1173ef440c4105e0b0e6d3e54 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Fri, 5 Jun 2020 18:14:05 +0000
Subject: [PATCH 16/87] Use IANA allocated GOST ClientCertificateTypes.
IANA has allocated numbers for GOST ClientCertificateType. Use them in
addition to private values (left in place for compatibility).
Diff from Dmitry Baryshkov <dbaryshkov@gmail.com>
Sponsored by ROSA Linux
ok inoguchi@ tb@
---
src/lib/libssl/s3_lib.c | 6 +++++-
src/lib/libssl/ssl3.h | 4 ++--
src/lib/libssl/tls1.h | 14 ++++++++------
3 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index f98ec3e09..e2fef7258 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.194 2020/06/05 17:58:32 jsing Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.195 2020/06/05 18:14:05 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -2553,6 +2553,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/ssl3.h b/src/lib/libssl/ssl3.h
index 30dc4c5d7..a102d1143 100644
--- a/src/lib/libssl/ssl3.h
+++ b/src/lib/libssl/ssl3.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl3.h,v 1.50 2020/03/12 17:01:53 jsing Exp $ */
+/* $OpenBSD: ssl3.h,v 1.51 2020/06/05 18:14:05 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -348,7 +348,7 @@ typedef struct ssl3_buffer_st {
* enough to contain all of the cert types defined either for
* SSLv3 and TLSv1.
*/
-#define SSL3_CT_NUMBER 11
+#define SSL3_CT_NUMBER 13
#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001
#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
diff --git a/src/lib/libssl/tls1.h b/src/lib/libssl/tls1.h
index 2230f0bab..8cd522658 100644
--- a/src/lib/libssl/tls1.h
+++ b/src/lib/libssl/tls1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls1.h,v 1.40 2020/01/02 06:23:16 jsing Exp $ */
+/* $OpenBSD: tls1.h,v 1.41 2020/06/05 18:14:05 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -735,16 +735,18 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS_CT_DSS_SIGN 2
#define TLS_CT_RSA_FIXED_DH 3
#define TLS_CT_DSS_FIXED_DH 4
+#define TLS_CT_GOST94_SIGN 21
+#define TLS_CT_GOST01_SIGN 22
#define TLS_CT_ECDSA_SIGN 64
#define TLS_CT_RSA_FIXED_ECDH 65
#define TLS_CT_ECDSA_FIXED_ECDH 66
-#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 */
+#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
+#define TLS_CT_NUMBER 13
#define TLS1_FINISH_MAC_LENGTH 12
--
2.17.1

View file

@ -0,0 +1,96 @@
From 4b3b3243b241fd08b36ef49f68891a837d723e05 Mon Sep 17 00:00:00 2001
From: tb <>
Date: Fri, 5 Jun 2020 18:44:42 +0000
Subject: [PATCH 17/87] Add a custom copy handler for AES key wrap
This is necessary because ctx->cipher_data is an EVP_AES_WRAP_CTX
containing a pointer to ctx->iv. EVP_CIPHER_CTX_copy() uses memcpy
to copy cipher_data to the target struct. The result is that the
copy contains a pointer to the wrong struct, which then leads to a
use-after-free. The custom copy handler fixes things up to avoid
that.
Issue reported by Guido Vranken
ok beck inoguchi jsing
---
src/lib/libcrypto/evp/e_aes.c | 36 ++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c
index 80eba8024..05ed00295 100644
--- a/src/lib/libcrypto/evp/e_aes.c
+++ b/src/lib/libcrypto/evp/e_aes.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_aes.c,v 1.41 2020/04/30 18:43:11 tb Exp $ */
+/* $OpenBSD: e_aes.c,v 1.42 2020/06/05 18:44:42 tb Exp $ */
/* ====================================================================
* Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
*
@@ -1636,9 +1636,35 @@ aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
return ret != 0 ? ret : -1;
}
+static int
+aes_wrap_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_AES_WRAP_CTX *wctx = c->cipher_data;
+
+ switch (type) {
+ case EVP_CTRL_COPY:
+ {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_WRAP_CTX *wctx_out = out->cipher_data;
+
+ if (wctx->iv != NULL) {
+ if (c->iv != wctx->iv)
+ return 0;
+
+ wctx_out->iv = out->iv;
+ }
+
+ return 1;
+ }
+ }
+
+ return -1;
+}
+
#define WRAP_FLAGS \
( EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | \
- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1 )
+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1 | \
+ EVP_CIPH_CUSTOM_COPY )
static const EVP_CIPHER aes_128_wrap = {
.nid = NID_id_aes128_wrap,
@@ -1652,7 +1678,7 @@ static const EVP_CIPHER aes_128_wrap = {
.ctx_size = sizeof(EVP_AES_WRAP_CTX),
.set_asn1_parameters = NULL,
.get_asn1_parameters = NULL,
- .ctrl = NULL,
+ .ctrl = aes_wrap_ctrl,
.app_data = NULL,
};
@@ -1674,7 +1700,7 @@ static const EVP_CIPHER aes_192_wrap = {
.ctx_size = sizeof(EVP_AES_WRAP_CTX),
.set_asn1_parameters = NULL,
.get_asn1_parameters = NULL,
- .ctrl = NULL,
+ .ctrl = aes_wrap_ctrl,
.app_data = NULL,
};
@@ -1696,7 +1722,7 @@ static const EVP_CIPHER aes_256_wrap = {
.ctx_size = sizeof(EVP_AES_WRAP_CTX),
.set_asn1_parameters = NULL,
.get_asn1_parameters = NULL,
- .ctrl = NULL,
+ .ctrl = aes_wrap_ctrl,
.app_data = NULL,
};
--
2.17.1

View file

@ -0,0 +1,191 @@
From 1bfa49e8d29f738ee5af179ad9aa12ee59dc6938 Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Wed, 10 Jun 2020 11:43:08 +0000
Subject: [PATCH 18/87] document PKCS7_get_signer_info(3)
---
src/lib/libcrypto/man/Makefile | 3 +-
src/lib/libcrypto/man/PKCS7_get_signer_info.3 | 62 +++++++++++++++++++
src/lib/libcrypto/man/PKCS7_new.3 | 6 +-
src/lib/libcrypto/man/PKCS7_sign.3 | 5 +-
src/lib/libcrypto/man/PKCS7_sign_add_signer.3 | 7 ++-
5 files changed, 75 insertions(+), 8 deletions(-)
create mode 100644 src/lib/libcrypto/man/PKCS7_get_signer_info.3
diff --git a/src/lib/libcrypto/man/Makefile b/src/lib/libcrypto/man/Makefile
index 7effea837..05b1a54c8 100644
--- a/src/lib/libcrypto/man/Makefile
+++ b/src/lib/libcrypto/man/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.166 2020/06/04 10:24:27 schwarze Exp $
+# $OpenBSD: Makefile,v 1.167 2020/06/10 11:43:07 schwarze Exp $
.include <bsd.own.mk>
@@ -220,6 +220,7 @@ MAN= \
PKCS7_decrypt.3 \
PKCS7_encrypt.3 \
PKCS7_final.3 \
+ PKCS7_get_signer_info.3 \
PKCS7_new.3 \
PKCS7_set_content.3 \
PKCS7_set_type.3 \
diff --git a/src/lib/libcrypto/man/PKCS7_get_signer_info.3 b/src/lib/libcrypto/man/PKCS7_get_signer_info.3
new file mode 100644
index 000000000..280f373ea
--- /dev/null
+++ b/src/lib/libcrypto/man/PKCS7_get_signer_info.3
@@ -0,0 +1,62 @@
+.\" $OpenBSD: PKCS7_get_signer_info.3,v 1.1 2020/06/10 11:43:08 schwarze Exp $
+.\"
+.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and 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.
+.\"
+.Dd $Mdocdate: June 10 2020 $
+.Dt PKCS7_GET_SIGNER_INFO 3
+.Os
+.Sh NAME
+.Nm PKCS7_get_signer_info
+.Nd retrieve signerInfos from a SignedData object
+.Sh SYNOPSIS
+.In openssl/pkcs7.h
+.Ft STACK_OF(PKCS7_SIGNER_INFO) *
+.Fn PKCS7_get_signer_info "PKCS7 *p7"
+.Sh DESCRIPTION
+This function retrieves the set of
+.Vt SignerInfo
+structures from the
+.Fa signerInfos
+field of
+.Fa p7 .
+.Pp
+These can subsequently be manipulated with the functions documented in
+.Xr PKCS7_add_attribute 3 .
+.Sh RETURN VALUES
+.Fn PKCS7_get_signer_info
+returns an internal pointer to a
+.Vt STACK_OF(PKCS7_SIGNER_INFO)
+object or
+.Dv NULL
+on failure.
+It fails if
+.Fa p7
+is
+.Dv NULL ,
+if it has no content,
+or if it is of a type other than
+.Vt SignedData
+or
+.Vt SignedAndEnvelopedData .
+.Sh SEE ALSO
+.Xr PKCS7_add_attribute 3 ,
+.Xr PKCS7_final 3 ,
+.Xr PKCS7_new 3 ,
+.Xr PKCS7_sign 3 ,
+.Xr PKCS7_sign_add_signer 3
+.Sh HISTORY
+.Fn PKCS7_get_signer_info
+first appeared in SSLeay 0.8.1 and has been available since
+.Ox 2.4 .
diff --git a/src/lib/libcrypto/man/PKCS7_new.3 b/src/lib/libcrypto/man/PKCS7_new.3
index c5eebe96d..151261a31 100644
--- a/src/lib/libcrypto/man/PKCS7_new.3
+++ b/src/lib/libcrypto/man/PKCS7_new.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_new.3,v 1.11 2020/06/04 10:24:27 schwarze Exp $
+.\" $OpenBSD: PKCS7_new.3,v 1.12 2020/06/10 11:43:08 schwarze Exp $
.\"
.\" Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 4 2020 $
+.Dd $Mdocdate: June 10 2020 $
.Dt PKCS7_NEW 3
.Os
.Sh NAME
@@ -251,6 +251,8 @@ frees
.Xr PKCS7_dataInit 3 ,
.Xr PKCS7_decrypt 3 ,
.Xr PKCS7_encrypt 3 ,
+.Xr PKCS7_final 3 ,
+.Xr PKCS7_get_signer_info 3 ,
.Xr PKCS7_ISSUER_AND_SERIAL_digest 3 ,
.Xr PKCS7_set_content 3 ,
.Xr PKCS7_set_type 3 ,
diff --git a/src/lib/libcrypto/man/PKCS7_sign.3 b/src/lib/libcrypto/man/PKCS7_sign.3
index c9b13680c..37257e60f 100644
--- a/src/lib/libcrypto/man/PKCS7_sign.3
+++ b/src/lib/libcrypto/man/PKCS7_sign.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_sign.3,v 1.12 2020/06/04 10:24:27 schwarze Exp $
+.\" $OpenBSD: PKCS7_sign.3,v 1.13 2020/06/10 11:43:08 schwarze Exp $
.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 4 2020 $
+.Dd $Mdocdate: June 10 2020 $
.Dt PKCS7_SIGN 3
.Os
.Sh NAME
@@ -233,6 +233,7 @@ The error can be obtained from
.Xr PKCS7_add_attribute 3 ,
.Xr PKCS7_encrypt 3 ,
.Xr PKCS7_final 3 ,
+.Xr PKCS7_get_signer_info 3 ,
.Xr PKCS7_new 3 ,
.Xr PKCS7_sign_add_signer 3 ,
.Xr PKCS7_verify 3
diff --git a/src/lib/libcrypto/man/PKCS7_sign_add_signer.3 b/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
index 28d327fef..195d6388c 100644
--- a/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
+++ b/src/lib/libcrypto/man/PKCS7_sign_add_signer.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PKCS7_sign_add_signer.3,v 1.12 2020/06/04 10:24:27 schwarze Exp $
+.\" $OpenBSD: PKCS7_sign_add_signer.3,v 1.13 2020/06/10 11:43:08 schwarze Exp $
.\" full merge up to: OpenSSL df75c2bf Dec 9 01:02:36 2018 +0100
.\"
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
@@ -49,12 +49,12 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 4 2020 $
+.Dd $Mdocdate: June 10 2020 $
.Dt PKCS7_SIGN_ADD_SIGNER 3
.Os
.Sh NAME
.Nm PKCS7_sign_add_signer
-.Nd add a signer PKCS7 signed data structure
+.Nd add a signer to a SignedData structure
.Sh SYNOPSIS
.In openssl/pkcs7.h
.Ft PKCS7_SIGNER_INFO *
@@ -178,6 +178,7 @@ In some cases of failure, the reason can be determined with
.Xr EVP_DigestInit 3 ,
.Xr PKCS7_add_attribute 3 ,
.Xr PKCS7_final 3 ,
+.Xr PKCS7_get_signer_info 3 ,
.Xr PKCS7_new 3 ,
.Xr PKCS7_sign 3
.Sh HISTORY
--
2.17.1

View file

@ -0,0 +1,52 @@
From eaaa6e46157f9dc7f8bd914215c9bc042c586e3b Mon Sep 17 00:00:00 2001
From: jmc <>
Date: Thu, 11 Jun 2020 18:03:19 +0000
Subject: [PATCH 19/87] wording tweaks from ross l richardson and tb; ok tb
---
src/lib/libcrypto/man/x509v3.cnf.5 | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/lib/libcrypto/man/x509v3.cnf.5 b/src/lib/libcrypto/man/x509v3.cnf.5
index 4d5aaa3e2..392c44d45 100644
--- a/src/lib/libcrypto/man/x509v3.cnf.5
+++ b/src/lib/libcrypto/man/x509v3.cnf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: x509v3.cnf.5,v 1.6 2019/06/06 01:06:59 schwarze Exp $
+.\" $OpenBSD: x509v3.cnf.5,v 1.7 2020/06/11 18:03:19 jmc Exp $
.\" full merge up to:
.\" OpenSSL man5/x509v3_config a41815f0 Mar 17 18:43:53 2017 -0700
.\" selective merge up to: OpenSSL 36cf10cf Oct 4 02:11:08 2017 -0400
@@ -51,7 +51,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 6 2019 $
+.Dd $Mdocdate: June 11 2020 $
.Dt X509V3.CNF 5
.Os
.Sh NAME
@@ -186,16 +186,16 @@ keyUsage=digitalSignature, nonRepudiation
keyUsage=critical, keyCertSign
.Ed
.Ss Extended key usage
-This extensions consists of a list of usages indicating purposes for
-which the certificate public key can be used for.
+This extension consists of a list of purposes for
+which the certificate public key can be used.
.Pp
These can either be object short names or the dotted numerical form of OIDs.
While any OID can be used, only certain values make sense.
In particular the following PKIX, NS and MS values are meaningful:
.Bl -column emailProtection
.It Em value Ta Em meaning
-.It Ic serverAuth Ta SSL/TLS web server authentication
-.It Ic clientAuth Ta SSL/TLS web client authentication
+.It Ic serverAuth Ta TLS server authentication
+.It Ic clientAuth Ta TLS client authentication
.It Ic codeSigning Ta code signing
.It Ic emailProtection Ta E-mail protection (S/MIME)
.It Ic timeStamping Ta trusted timestamping
--
2.17.1

View file

@ -0,0 +1,367 @@
From 0bce9751943e4ed359b05bb17d9cec8d3a36da59 Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Fri, 12 Jun 2020 11:37:42 +0000
Subject: [PATCH 20/87] document PEM_ASN1_read(3) and PEM_ASN1_read_bio(3);
tweaks and OK tb@
---
src/lib/libcrypto/man/Makefile | 3 +-
src/lib/libcrypto/man/PEM_ASN1_read.3 | 171 ++++++++++++++++++
src/lib/libcrypto/man/PEM_bytes_read_bio.3 | 52 +++++-
src/lib/libcrypto/man/PEM_read.3 | 7 +-
.../libcrypto/man/PEM_read_bio_PrivateKey.3 | 10 +-
5 files changed, 236 insertions(+), 7 deletions(-)
create mode 100644 src/lib/libcrypto/man/PEM_ASN1_read.3
diff --git a/src/lib/libcrypto/man/Makefile b/src/lib/libcrypto/man/Makefile
index 05b1a54c8..c613fdc29 100644
--- a/src/lib/libcrypto/man/Makefile
+++ b/src/lib/libcrypto/man/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.167 2020/06/10 11:43:07 schwarze Exp $
+# $OpenBSD: Makefile,v 1.168 2020/06/12 11:37:42 schwarze Exp $
.include <bsd.own.mk>
@@ -203,6 +203,7 @@ MAN= \
OPENSSL_malloc.3 \
OPENSSL_sk_new.3 \
OpenSSL_add_all_algorithms.3 \
+ PEM_ASN1_read.3 \
PEM_bytes_read_bio.3 \
PEM_read.3 \
PEM_read_bio_PrivateKey.3 \
diff --git a/src/lib/libcrypto/man/PEM_ASN1_read.3 b/src/lib/libcrypto/man/PEM_ASN1_read.3
new file mode 100644
index 000000000..cea0c2df6
--- /dev/null
+++ b/src/lib/libcrypto/man/PEM_ASN1_read.3
@@ -0,0 +1,171 @@
+.\" $OpenBSD: PEM_ASN1_read.3,v 1.1 2020/06/12 11:37:42 schwarze Exp $
+.\"
+.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and 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.
+.\"
+.Dd $Mdocdate: June 12 2020 $
+.Dt PEM_ASN1_READ 3
+.Os
+.Sh NAME
+.Nm d2i_of_void ,
+.Nm PEM_ASN1_read ,
+.Nm PEM_ASN1_read_bio
+.Nd PEM and DER decode an arbitrary ASN.1 value
+.Sh SYNOPSIS
+.In openssl/pem.h
+.Ft typedef void *
+.Fo d2i_of_void
+.Fa "void **val_out"
+.Fa "const unsigned char **der_in"
+.Fa "long length"
+.Fc
+.Ft void *
+.Fo PEM_ASN1_read
+.Fa "d2i_of_void *d2i"
+.Fa "const char *name"
+.Fa "FILE *in_fp"
+.Fa "void **val_out"
+.Fa "pem_password_cb *cb"
+.Fa "void *u"
+.Fc
+.Ft void *
+.Fo PEM_ASN1_read_bio
+.Fa "d2i_of_void *d2i"
+.Fa "const char *name"
+.Fa "BIO *in_bp"
+.Fa "void **val_out"
+.Fa "pem_password_cb *cb"
+.Fa "void *u"
+.Fc
+.Sh DESCRIPTION
+These functions read one object from
+.Fa in_fp
+or
+.Fa in_bp
+and perform both PEM and DER decoding.
+They are needed when more specific decoding functions
+like those documented in
+.Xr PEM_read_bio_PrivateKey 3
+and
+.Xr PEM_read_SSL_SESSION 3
+are inadequate for the type
+.Fa name .
+.Pp
+For PEM decoding,
+.Xr PEM_bytes_read_bio 3
+is called internally.
+Consequently, the first object of type
+.Fa name
+is returned and preceding objects of other types are discarded.
+If necessary, data is decrypted, using
+.Fa cb
+and/or
+.Fa u
+if they are not
+.Dv NULL ,
+as described in the
+.Xr pem_password_cb 3
+manual page.
+.Pp
+For subsequent DER decoding, pass a
+.Fa d2i
+callback function that is adequate for the type
+.Fa name ,
+typically returning a pointer of a type more specific than
+.Ft void * .
+For example,
+.Xr d2i_ASN1_TYPE 3
+can always be used and its manual page describes the required
+behaviour of the callback function to be passed.
+Normally, passing a more specific function is more useful;
+candidate functions can be found with
+.Ql man -k Nm~^d2i_ .
+.Pp
+For the
+.Fa name
+argument, the
+.Dv PEM_STRING_*
+string constants defined in
+.In openssl/pem.h
+can be used.
+.Pp
+The
+.Fa val_out
+argument is useless and its many dangers are described in detail in the
+.Xr d2i_ASN1_TYPE 3
+manual page.
+To reduce the risk of bugs, always passing
+.Dv NULL
+is recommended.
+.Sh RETURN VALUES
+These functions return a pointer to the decoded object or
+.Dv NULL
+if an error occurs.
+They fail if
+.Xr PEM_bytes_read_bio 3
+fails, for example because of invalid syntax in the input, an unknown
+encryption, or an invalid passphrase entered by the user.
+They also fail if
+.Fa d2i
+returns
+.Dv NULL ,
+for example due to DER decoding errors.
+.Pp
+.Fn PEM_ASN1_read
+may also fail if memory is exhausted.
+.Sh EXAMPLES
+Typical usage of
+.Fn PEM_ASN1_read
+is demonstrated by the implementation of the more specific function
+to PEM and DER decode an X.509 certificate:
+.Bd -literal -offset 2n
+X509 *
+PEM_read_X509(FILE *fp, X509 **val_out, pem_password_cb *cb, void *u)
+{
+ return PEM_ASN1_read((d2i_of_void *)d2i_X509, PEM_STRING_X509,
+ fp, (void **)val_out, cb, u);
+}
+.Ed
+.Sh ERRORS
+Diagnostics that can be retrieved with
+.Xr ERR_get_error 3 ,
+.Xr ERR_GET_REASON 3 ,
+and
+.Xr ERR_reason_error_string 3
+include:
+.Bl -tag -width Ds
+.It Dv ERR_R_BUF_LIB Qq "BUF lib"
+.Fn PEM_ASN1_read
+failed to set up a temporary BIO,
+for example because memory was exhausted.
+.It Dv ERR_R_ASN1_LIB Qq "ASN1 lib"
+.Fa d2i
+returned
+.Dv NULL ,
+for example due to a DER syntax error.
+.El
+.Pp
+Additional types of errors can result from
+.Xr PEM_bytes_read_bio 3 .
+.Sh SEE ALSO
+.Xr BIO_new 3 ,
+.Xr d2i_ASN1_TYPE 3 ,
+.Xr PEM_bytes_read_bio 3 ,
+.Xr PEM_read 3 ,
+.Xr PEM_read_bio_PrivateKey 3 ,
+.Xr PEM_read_SSL_SESSION 3
+.Sh HISTORY
+These functions first appeared in SSLeay 0.5.1
+and have been available since
+.Ox 2.4 .
diff --git a/src/lib/libcrypto/man/PEM_bytes_read_bio.3 b/src/lib/libcrypto/man/PEM_bytes_read_bio.3
index b3cb143cf..63b8a58d9 100644
--- a/src/lib/libcrypto/man/PEM_bytes_read_bio.3
+++ b/src/lib/libcrypto/man/PEM_bytes_read_bio.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PEM_bytes_read_bio.3,v 1.2 2018/03/22 21:08:22 schwarze Exp $
+.\" $OpenBSD: PEM_bytes_read_bio.3,v 1.3 2020/06/12 11:37:42 schwarze Exp $
.\" OpenSSL PEM_bytes_read_bio.pod 7671342e Feb 29 15:47:12 2016 -0600
.\"
.\" This file was written by Benjamin Kaduk <bkaduk at akamai dot com>.
@@ -48,7 +48,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: March 22 2018 $
+.Dd $Mdocdate: June 12 2020 $
.Dt PEM_BYTES_READ_BIO 3
.Os
.Sh NAME
@@ -86,6 +86,8 @@ The password callback
and rock
.Fa u
are used to obtain the decryption passphrase, if applicable.
+For more details, see
+.Xr pem_password_cb 3 .
.Pp
Some data types have compatibility aliases, such as a file containing
X509 CERTIFICATE matching a request for the deprecated type CERTIFICATE.
@@ -107,7 +109,53 @@ The caller must free the storage pointed to by
.Sh RETURN VALUES
.Fn PEM_bytes_read_bio
returns 1 for success or 0 for failure.
+.Sh ERRORS
+Diagnostics that can be retrieved with
+.Xr ERR_get_error 3 ,
+.Xr ERR_GET_REASON 3 ,
+and
+.Xr ERR_reason_error_string 3
+include:
+.Bl -tag -width Ds
+.It Dv PEM_R_NO_START_LINE Qq no start line
+No more PEM objects were found in the input.
+This can happen when the input contains no PEM objects at all,
+or only objects that do not match the type
+.Fa name .
+.It Dv PEM_R_NOT_PROC_TYPE Qq not proc type
+The first PEM header does not start with
+.Qq "Proc-Type: " .
+.It Dv PEM_R_NOT_ENCRYPTED Qq not encrypted
+The Proc-Type header differs from
+.Qq 4,ENCRYPTED .
+.It Dv PEM_R_SHORT_HEADER Qq short header
+The Proc-Type header is the last header line.
+.It Dv PEM_R_NOT_DEK_INFO Qq not dek info
+The second PEM header does not start with
+.Qq "DEK-Info: " .
+.It Dv PEM_R_UNSUPPORTED_ENCRYPTION Qq unsupported encryption
+The cipher name given in the DEK-Info header is unknown to
+.Xr EVP_get_cipherbyname 3 .
+.It Dv PEM_R_BAD_IV_CHARS Qq "bad iv chars"
+The word following the cipher name in the DEK-Info header
+contains bytes that are not hexadecimal digits.
+This also happens when the initialization vector is missing or too short.
+.It Dv PEM_R_BAD_PASSWORD_READ Qq bad password read
+.Fa cb
+reported failure.
+This may for example happen when the user mistypes the password.
+.It Dv PEM_R_BAD_DECRYPT Qq bad decrypt
+.Xr EVP_DecryptInit_ex 3 ,
+.Xr EVP_DecryptUpdate 3 ,
+or
+.Xr EVP_DecryptFinal_ex 3
+failed.
+.El
+.Pp
+Additional types of errors can result from
+.Xr PEM_read_bio 3 .
.Sh SEE ALSO
+.Xr PEM_ASN1_read 3 ,
.Xr PEM_read 3 ,
.Xr PEM_read_bio_PrivateKey 3
.Sh HISTORY
diff --git a/src/lib/libcrypto/man/PEM_read.3 b/src/lib/libcrypto/man/PEM_read.3
index 5648aa014..1469ccd55 100644
--- a/src/lib/libcrypto/man/PEM_read.3
+++ b/src/lib/libcrypto/man/PEM_read.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PEM_read.3,v 1.9 2019/06/10 14:58:48 schwarze Exp $
+.\" $OpenBSD: PEM_read.3,v 1.10 2020/06/12 11:37:42 schwarze Exp $
.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
.\"
.\" This file was written by Viktor Dukhovni
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 10 2019 $
+.Dd $Mdocdate: June 12 2020 $
.Dt PEM_READ 3
.Os
.Sh NAME
@@ -279,8 +279,11 @@ is likely meaningless if these functions fail.
.Sh SEE ALSO
.Xr crypto 3 ,
.Xr d2i_PKCS8PrivateKey_bio 3 ,
+.Xr PEM_ASN1_read 3 ,
.Xr PEM_bytes_read_bio 3 ,
.Xr PEM_read_bio_PrivateKey 3 ,
+.Xr PEM_read_SSL_SESSION 3 ,
+.Xr PEM_write_bio_CMS_stream 3 ,
.Xr PEM_write_bio_PKCS7_stream 3
.Sh HISTORY
.Fn PEM_write ,
diff --git a/src/lib/libcrypto/man/PEM_read_bio_PrivateKey.3 b/src/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
index cf45356cf..3799baa04 100644
--- a/src/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
+++ b/src/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PEM_read_bio_PrivateKey.3,v 1.16 2019/11/02 15:25:34 schwarze Exp $
+.\" $OpenBSD: PEM_read_bio_PrivateKey.3,v 1.17 2020/06/12 11:37:42 schwarze Exp $
.\" full merge up to:
.\" OpenSSL man3/PEM_read_bio_PrivateKey.pod 18bad535 Apr 9 15:13:55 2019 +0100
.\" OpenSSL man3/PEM_read_CMS.pod 83cf7abf May 29 13:07:08 2018 +0100
@@ -51,7 +51,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: November 2 2019 $
+.Dd $Mdocdate: June 12 2020 $
.Dt PEM_READ_BIO_PRIVATEKEY 3
.Os
.Sh NAME
@@ -770,6 +770,9 @@ will be used to collectively refer to the
and
.Fn PEM_write_TYPE
functions.
+If no set of specific functions exists for a given type,
+.Xr PEM_ASN1_read 3
+can be used instead.
.Pp
The
.Sy PrivateKey
@@ -1266,8 +1269,11 @@ pass_cb(char *buf, int size, int rwflag, void *u)
.Sh SEE ALSO
.Xr BIO_new 3 ,
.Xr DSA_new 3 ,
+.Xr PEM_ASN1_read 3 ,
.Xr PEM_bytes_read_bio 3 ,
.Xr PEM_read 3 ,
+.Xr PEM_read_SSL_SESSION 3 ,
+.Xr PEM_write_bio_CMS_stream 3 ,
.Xr PEM_write_bio_PKCS7_stream 3 ,
.Xr RSA_new 3 ,
.Xr X509_CRL_new 3 ,
--
2.17.1

View file

@ -0,0 +1,42 @@
From ea838d97bb686ea74dabf19a2b3c08ef4aeb813f Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Fri, 12 Jun 2020 12:15:59 +0000
Subject: [PATCH 21/87] add a comment saying that name_cmp() is intentionally
undocumented; tb@ agrees that it should not be part of the public API
---
src/lib/libcrypto/man/X509_cmp.3 | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/lib/libcrypto/man/X509_cmp.3 b/src/lib/libcrypto/man/X509_cmp.3
index 1734d6a74..bd168c2a6 100644
--- a/src/lib/libcrypto/man/X509_cmp.3
+++ b/src/lib/libcrypto/man/X509_cmp.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: X509_cmp.3,v 1.1 2019/08/20 13:27:19 schwarze Exp $
+.\" $OpenBSD: X509_cmp.3,v 1.2 2020/06/12 12:15:59 schwarze Exp $
.\" full merge up to: OpenSSL ea5d4b89 Jun 6 11:42:02 2019 +0800
.\"
.\" This file is a derived work.
@@ -65,7 +65,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: August 20 2019 $
+.Dd $Mdocdate: June 12 2020 $
.Dt X509_CMP 3
.Os
.Sh NAME
@@ -77,6 +77,9 @@
.Nm X509_CRL_cmp ,
.Nm X509_CRL_match
.Nd compare X.509 certificates and related values
+.\" The function name_cmp() is intentionally undocumented.
+.\" It was a mistake to make it public in the first place,
+.\" and it is no longer part of the public API in OpenSSL 1.1.
.Sh SYNOPSIS
.In openssl/x509.h
.Ft int
--
2.17.1

View file

@ -0,0 +1,46 @@
From 45c46ae34710091d5dab6d2f1beaf438ab3fbfac Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Fri, 12 Jun 2020 18:16:13 +0000
Subject: [PATCH 22/87] add my Copyright and license, which i forgot when
adding a significant amount of text, the ERRORS section, in the previous
commit
---
src/lib/libcrypto/man/PEM_bytes_read_bio.3 | 23 +++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/lib/libcrypto/man/PEM_bytes_read_bio.3 b/src/lib/libcrypto/man/PEM_bytes_read_bio.3
index 63b8a58d9..d3a664ba7 100644
--- a/src/lib/libcrypto/man/PEM_bytes_read_bio.3
+++ b/src/lib/libcrypto/man/PEM_bytes_read_bio.3
@@ -1,7 +1,24 @@
-.\" $OpenBSD: PEM_bytes_read_bio.3,v 1.3 2020/06/12 11:37:42 schwarze Exp $
-.\" OpenSSL PEM_bytes_read_bio.pod 7671342e Feb 29 15:47:12 2016 -0600
+.\" $OpenBSD: PEM_bytes_read_bio.3,v 1.4 2020/06/12 18:16:13 schwarze Exp $
+.\" selective merge up to:
+.\" OpenSSL PEM_bytes_read_bio.pod 7671342e Feb 29 15:47:12 2016 -0600
.\"
-.\" This file was written by Benjamin Kaduk <bkaduk at akamai dot com>.
+.\" This file is a derived work.
+.\" The changes are covered by the following Copyright and license:
+.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and 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.
+.\"
+.\" The original file was written by Benjamin Kaduk <bkaduk at akamai dot com>.
.\" Copyright (c) 2017 The OpenSSL Project. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
--
2.17.1

View file

@ -0,0 +1,430 @@
From 8b13cacf2286f4647d6fe7d975a090f2e82b58d1 Mon Sep 17 00:00:00 2001
From: schwarze <>
Date: Mon, 15 Jun 2020 14:13:14 +0000
Subject: [PATCH 23/87] Document PEM_def_callback(3). Move pem_password_cb(3)
to the file PEM_read(3) and rewrite its description from scratch for
precision and conciseness. Plus some minor improvements in the vicinity.
Tweaks and OK tb@.
---
src/lib/libcrypto/man/PEM_bytes_read_bio.3 | 36 +++--
src/lib/libcrypto/man/PEM_read.3 | 146 +++++++++++++++---
.../libcrypto/man/PEM_read_bio_PrivateKey.3 | 82 ++--------
3 files changed, 158 insertions(+), 106 deletions(-)
diff --git a/src/lib/libcrypto/man/PEM_bytes_read_bio.3 b/src/lib/libcrypto/man/PEM_bytes_read_bio.3
index d3a664ba7..d1148edfe 100644
--- a/src/lib/libcrypto/man/PEM_bytes_read_bio.3
+++ b/src/lib/libcrypto/man/PEM_bytes_read_bio.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PEM_bytes_read_bio.3,v 1.4 2020/06/12 18:16:13 schwarze Exp $
+.\" $OpenBSD: PEM_bytes_read_bio.3,v 1.5 2020/06/15 14:13:14 schwarze Exp $
.\" selective merge up to:
.\" OpenSSL PEM_bytes_read_bio.pod 7671342e Feb 29 15:47:12 2016 -0600
.\"
@@ -65,7 +65,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 12 2020 $
+.Dd $Mdocdate: June 15 2020 $
.Dt PEM_BYTES_READ_BIO 3
.Os
.Sh NAME
@@ -79,31 +79,31 @@
.Fa "long *plen"
.Fa "char **pnm"
.Fa "const char *name"
-.Fa "BIO *bp"
+.Fa "BIO *in_bp"
.Fa "pem_password_cb *cb"
.Fa "void *u"
.Fc
.Sh DESCRIPTION
.Fn PEM_bytes_read_bio
-reads PEM-formatted (RFC 1421) data from the BIO
-.Fa bp
-for the data type given in
+reads and PEM decodes the first object of type
.Fa name
-(RSA PRIVATE KEY, CERTIFICATE, etc.).
+.Pq e.g. RSA PRIVATE KEY, CERTIFICATE, etc.\&
+from
+.Fa in_bp .
If multiple PEM-encoded data structures are present in the same stream,
-.Fn PEM_bytes_read_bio
-will skip non-matching data types and continue reading.
-Non-PEM data present in the stream may cause an error.
+it skips non-matching data types and continues reading.
+Before reading each PEM object, lines not starting with
+.Qq "-----BEGIN "
+are also skipped; see
+.Xr PEM_read_bio 3
+for details of PEM parsing.
.Pp
The PEM header may indicate that the following data is encrypted; if so,
-the data will be decrypted, waiting on user input to supply a passphrase
-if needed.
-The password callback
+the data is decrypted, optionally using
.Fa cb
-and rock
-.Fa u
-are used to obtain the decryption passphrase, if applicable.
-For more details, see
+and
+.Fa u ,
+as described in
.Xr pem_password_cb 3 .
.Pp
Some data types have compatibility aliases, such as a file containing
@@ -175,6 +175,8 @@ Additional types of errors can result from
.Xr PEM_ASN1_read 3 ,
.Xr PEM_read 3 ,
.Xr PEM_read_bio_PrivateKey 3
+.Sh STANDARDS
+RFC 1421: Privacy Enhancement for Internet Electronic Mail (PEM), Part I
.Sh HISTORY
.Fn PEM_bytes_read_bio
first appeared in OpenSSL 0.9.7 and has been available since
diff --git a/src/lib/libcrypto/man/PEM_read.3 b/src/lib/libcrypto/man/PEM_read.3
index 1469ccd55..49cdd0f3c 100644
--- a/src/lib/libcrypto/man/PEM_read.3
+++ b/src/lib/libcrypto/man/PEM_read.3
@@ -1,7 +1,24 @@
-.\" $OpenBSD: PEM_read.3,v 1.10 2020/06/12 11:37:42 schwarze Exp $
-.\" OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
+.\" $OpenBSD: PEM_read.3,v 1.11 2020/06/15 14:13:14 schwarze Exp $
+.\" full merge up to: OpenSSL 83cf7abf May 29 13:07:08 2018 +0100
.\"
-.\" This file was written by Viktor Dukhovni
+.\" This file is a derived work.
+.\" The changes are covered by the following Copyright and license:
+.\"
+.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and 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.
+.\"
+.\" The original file was written by Viktor Dukhovni
.\" and by Rich Salz <rsalz@openssl.org>.
.\" Copyright (c) 2016 The OpenSSL Project. All rights reserved.
.\"
@@ -49,7 +66,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 12 2020 $
+.Dd $Mdocdate: June 15 2020 $
.Dt PEM_READ 3
.Os
.Sh NAME
@@ -57,8 +74,10 @@
.Nm PEM_write_bio ,
.Nm PEM_read ,
.Nm PEM_read_bio ,
+.Nm PEM_get_EVP_CIPHER_INFO ,
.Nm PEM_do_header ,
-.Nm PEM_get_EVP_CIPHER_INFO
+.Nm PEM_def_callback ,
+.Nm pem_password_cb
.Nd PEM encoding routines
.Sh SYNOPSIS
.In openssl/pem.h
@@ -107,6 +126,20 @@
.Fa "pem_password_cb *cb"
.Fa "void *u"
.Fc
+.Ft int
+.Fo PEM_def_callback
+.Fa "char *password"
+.Fa "int size"
+.Fa "int verify"
+.Fa "void *u"
+.Fc
+.Ft typedef int
+.Fo pem_password_cb
+.Fa "char *password"
+.Fa "int size"
+.Fa "int verify"
+.Fa "void *u"
+.Fc
.Sh DESCRIPTION
These functions read and write PEM-encoded objects, using the PEM type
.Fa name ,
@@ -224,34 +257,83 @@ unknown or some internal error happens, 0 is returned.
can then be used to decrypt the data if the header indicates encryption.
The
.Fa cinfo
-argument is a pointer to the structure initialized by the previous call
+argument is a pointer to the structure initialized by a preceding call
to
.Fn PEM_get_EVP_CIPHER_INFO .
+If that structure indicates the absence of encryption,
+.Fn PEM_do_header
+returns sucessfully without taking any action.
The
.Fa data
and
.Fa len
-arguments are those returned by the previous call to
+arguments are used both to pass in the encrypted data that was
+returned in the same arguments from the preceding call to
.Fn PEM_read
or
-.Fn PEM_read_bio .
+.Fn PEM_read_bio
+and to pass out the decrypted data.
+.Pp
+The callback function
+.Fa cb
+is used to obtain the encryption
+.Fa password ;
+if
+.Fa cb
+is
+.Dv NULL ,
+.Fn PEM_def_callback
+is used instead.
The
+.Fa password
+buffer needs to be at least
+.Fa size
+bytes long.
+.Fn PEM_def_callback
+silently truncates the NUL-terminated byte string
+.Fa u
+to at most
+.Fa num
+bytes and copies it into
+.Fa password
+without a terminating NUL byte.
+If
+.Fa u
+is
+.Dv NULL ,
+.Fn PEM_def_callback
+instead prompts the user for the password with echoing turned off
+by calling
+.Xr EVP_read_pw_string_min 3
+internally.
+In this case, the
+.Fa size
+is silently reduced to at most
+.Dv BUFSIZ
+and at most
+.Fa size No \- 1
+bytes are accepted from the user and copied into the byte string buffer
+.Fa password .
+A callback function
.Fa cb
-and
+supplied by the application may use
.Fa u
-arguments make it possible to override the default password prompt
-function as described in
-.Xr PEM_read_PrivateKey 3 .
-On successful completion, the
-.Fa data
-is decrypted in place, and
-.Fa len
-is updated to indicate the plaintext length.
+for a different purpose than
+.Fn PEM_def_callback
+does, e.g., as auxiliary data to use while acquiring the password.
+For example, a GUI application might pass a window handle.
+If the
+.Fa verify
+flag is non-zero, the user is prompted twice for the password to
+make typos less likely and it is checked that both inputs agree.
+This flag is not set by
+.Fn PEM_do_header
+nor by other read functions.
.Pp
If the data is a priori known to not be encrypted, then neither
-.Fn PEM_do_header
-nor
.Fn PEM_get_EVP_CIPHER_INFO
+nor
+.Fn PEM_do_header
need to be called.
.Sh RETURN VALUES
.Fn PEM_read
@@ -276,6 +358,28 @@ return 1 on success or 0 on failure.
The
.Fa data
is likely meaningless if these functions fail.
+.Pp
+.Fn PEM_def_callback
+returns the number of bytes stored into
+.Fa buf
+or a negative value on failure, and
+.Fa cb
+is expected to behave in the same way.
+If
+.Fa u
+is
+.Dv NULL ,
+.Fn PEM_def_callback
+fails if
+.Fa num
+is less than 5
+or if an error occurs trying to prompt the user for the password.
+Otherwise, it fails when
+.Fa num
+is negative.
+The details of the circumstances that cause
+.Fa cb
+to fail may differ.
.Sh SEE ALSO
.Xr crypto 3 ,
.Xr d2i_PKCS8PrivateKey_bio 3 ,
@@ -299,3 +403,7 @@ and
first appeared in SSLeay 0.6.0.
These functions have been available since
.Ox 2.4 .
+.Pp
+.Fn PEM_def_callback
+first appeared in OpenSSL 0.9.7 and has been available since
+.Ox 3.2 .
diff --git a/src/lib/libcrypto/man/PEM_read_bio_PrivateKey.3 b/src/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
index 3799baa04..cc58640b1 100644
--- a/src/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
+++ b/src/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: PEM_read_bio_PrivateKey.3,v 1.17 2020/06/12 11:37:42 schwarze Exp $
+.\" $OpenBSD: PEM_read_bio_PrivateKey.3,v 1.18 2020/06/15 14:13:14 schwarze Exp $
.\" full merge up to:
.\" OpenSSL man3/PEM_read_bio_PrivateKey.pod 18bad535 Apr 9 15:13:55 2019 +0100
.\" OpenSSL man3/PEM_read_CMS.pod 83cf7abf May 29 13:07:08 2018 +0100
@@ -51,11 +51,10 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 12 2020 $
+.Dd $Mdocdate: June 15 2020 $
.Dt PEM_READ_BIO_PRIVATEKEY 3
.Os
.Sh NAME
-.Nm pem_password_cb ,
.Nm PEM_read_bio_PrivateKey ,
.Nm PEM_read_PrivateKey ,
.Nm PEM_write_bio_PrivateKey ,
@@ -149,13 +148,6 @@
.Nd PEM routines
.Sh SYNOPSIS
.In openssl/pem.h
-.Ft typedef int
-.Fo pem_password_cb
-.Fa "char *buf"
-.Fa "int size"
-.Fa "int rwflag"
-.Fa "void *u"
-.Fc
.Ft EVP_PKEY *
.Fo PEM_read_bio_PrivateKey
.Fa "BIO *bp"
@@ -754,7 +746,9 @@
.Sh DESCRIPTION
The PEM functions read or write structures in PEM format.
In this sense PEM format is simply base64-encoded data surrounded by
-header lines.
+header lines; see
+.Xr PEM_read 3
+for more details.
.Pp
For more details about the meaning of arguments see the
.Sx PEM function arguments
@@ -1050,10 +1044,14 @@ If this parameter is set to
.Dv NULL ,
then the private key is written in unencrypted form.
.Pp
-The
+The optional arguments
+.Fa u
+and
.Fa cb
-argument is the callback to use when querying for the passphrase used
-for encrypted PEM structures (normally only private keys).
+are a passphrase used for encrypting a PEM structure
+or a callback to obtain the passphrase; see
+.Xr pem_password_cb 3
+for details.
.Pp
For the PEM write routines, if the
.Fa kstr
@@ -1066,62 +1064,6 @@ bytes at
are used as the passphrase and
.Fa cb
is ignored.
-.Pp
-If the
-.Fa cb
-parameter is set to
-.Dv NULL
-and the
-.Fa u
-parameter is not
-.Dv NULL ,
-then the
-.Fa u
-parameter is interpreted as a null terminated string to use as the
-passphrase.
-If both
-.Fa cb
-and
-.Fa u
-are
-.Dv NULL ,
-then the default callback routine is used, which will typically
-prompt for the passphrase on the current terminal with echoing
-turned off.
-.Pp
-The default passphrase callback is sometimes inappropriate (for example
-in a GUI application) so an alternative can be supplied.
-The callback routine has the following form:
-.Bd -filled -offset inset
-.Ft int
-.Fo cb
-.Fa "char *buf"
-.Fa "int size"
-.Fa "int rwflag"
-.Fa "void *u"
-.Fc
-.Ed
-.Pp
-.Fa buf
-is the buffer to write the passphrase to.
-.Fa size
-is the maximum length of the passphrase, i.e. the size of
-.Fa buf .
-.Fa rwflag
-is a flag which is set to 0 when reading and 1 when writing.
-A typical routine will ask the user to verify the passphrase (for
-example by prompting for it twice) if
-.Fa rwflag
-is 1.
-The
-.Fa u
-parameter has the same value as the
-.Fa u
-parameter passed to the PEM routine.
-It allows arbitrary data to be passed to the callback by the application
-(for example a window handle in a GUI application).
-The callback must return the number of characters in the passphrase
-or -1 if an error occurred.
.Ss PEM encryption format
This old
.Sy PrivateKey
--
2.17.1

View file

@ -0,0 +1,115 @@
From d7a02c1cb2864937d134b1285f5980f72dc9e650 Mon Sep 17 00:00:00 2001
From: tb <>
Date: Mon, 15 Jun 2020 15:25:46 +0000
Subject: [PATCH 24/87] Document EVP_read_pw_string_min(3)
Add detailed information on the return values of all the functions
in this page and remove the previous incorrect information.
tweaks & ok schwarze
---
src/lib/libcrypto/man/des_read_pw.3 | 50 +++++++++++++++++++++++++----
1 file changed, 44 insertions(+), 6 deletions(-)
diff --git a/src/lib/libcrypto/man/des_read_pw.3 b/src/lib/libcrypto/man/des_read_pw.3
index 8c63a65fd..55d36ef72 100644
--- a/src/lib/libcrypto/man/des_read_pw.3
+++ b/src/lib/libcrypto/man/des_read_pw.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: des_read_pw.3,v 1.8 2018/03/27 17:35:50 schwarze Exp $
+.\" $OpenBSD: des_read_pw.3,v 1.9 2020/06/15 15:25:46 tb Exp $
.\" OpenSSL doc/crypto/ui_compat.pod May 14 11:28:00 2006 +0000
.\" OpenSSL doc/crypto/des.pod 2a9aca32 Oct 25 08:44:10 2001 +0000
.\"
@@ -50,13 +50,14 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: March 27 2018 $
+.Dd $Mdocdate: June 15 2020 $
.Dt DES_READ_PW 3
.Os
.Sh NAME
.Nm des_read_pw ,
.Nm des_read_pw_string ,
-.Nm EVP_read_pw_string
+.Nm EVP_read_pw_string ,
+.Nm EVP_read_pw_string_min
.Nd compatibility user interface functions
.Sh SYNOPSIS
.In openssl/ui_compat.h
@@ -83,6 +84,14 @@
.Fa "const char *prompt"
.Fa "int verify"
.Fc
+.Ft int
+.Fo EVP_read_pw_string_min
+.Fa "char *buf"
+.Fa "int min_length"
+.Fa "int length"
+.Fa "const char *prompt"
+.Fa "int verify"
+.Fc
.Sh DESCRIPTION
The DES library contained a few routines to prompt for passwords.
These aren't necessarily dependent on DES, and have therefore become
@@ -107,8 +116,6 @@ The second password is stored in
which must therefore also be at least
.Fa length
bytes.
-A return code of -1 indicates a system error, 1 failure due to use
-interaction, and 0 is success.
.Pp
.Fn des_read_pw_string
is a variant of
@@ -126,8 +133,34 @@ uses
.Dv BUFSIZ .
.Pp
.Fn EVP_read_pw_string
-is functionally similar to
+and
+.Fn EVP_read_pw_string_min
+are functionally similar to
.Fn des_read_pw_string .
+.Fn EVP_read_pw_string_min
+additionally checks that the password is at least
+.Fa min_length
+bytes long.
+.Sh RETURN VALUES
+These functions return 0 on success and a negative value on failure.
+.Pp
+They return -1 if
+.Fa length
+is less than or equal to zero or on memory allocation failure.
+They return -1 or -2 if the internal call to
+.Xr UI_process 3
+fails.
+.Pp
+In addition,
+.Fa EVP_read_pw_string_min
+returns -1 if
+.Fa min_length
+is negative, if
+.Fa length
+is less than or equal to
+.Fa min_length ,
+or if the user entered a password shorter than
+.Fa min_length .
.Sh SEE ALSO
.Xr UI_new 3
.Sh HISTORY
@@ -139,6 +172,11 @@ first appeared in SSLeay 0.5.1.
first appeared in SSLeay 0.8.0.
These functions have been available since
.Ox 2.4 .
+.Pp
+.Fn EVP_read_pw_string_min
+first appeared in OpenSSL 1.0.0
+and has been available since
+.Ox 4.9 .
.Sh AUTHORS
.An Richard Levitte Aq Mt richard@levitte.org
for the OpenSSL project.
--
2.17.1

View file

@ -0,0 +1,44 @@
From 2b6729397b700f453dbf3797f91dd8297c61cf21 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sat, 28 Mar 2020 19:08:50 +0300
Subject: [PATCH 25/87] gost: populate params tables with new curves
Allow users to specify new curves via strings.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
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 282a21041..9764964cd 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.17.1

View file

@ -0,0 +1,112 @@
From 4db6b93111cff924d0ba6650ef351939d67e94a5 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 18 Mar 2020 14:05:08 +0300
Subject: [PATCH 26/87] gost: use ECerror to report EC errors
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 <dbaryshkov@gmail.com>
---
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 27a95f206..0e9521178 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 0af39f21b..74f8cab9d 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 0eb1d873d..0e0cae99e 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.17.1

View file

@ -0,0 +1,92 @@
From c9c184c2ea46015df5fd582f0b90c50e80806131 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 18 Mar 2020 14:14:31 +0300
Subject: [PATCH 27/87] gost: support new PublicKeyParameters format
Add support for updated PublicKeyParameters format as defined by
draft-deremin-rfc4491-bis.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
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 265216277..703d64070 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 = &ASN1_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 0e9521178..7cb70ed42 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, &params->data);
if (params->length <= 0) {
--
2.17.1

View file

@ -0,0 +1,259 @@
From b24d8544474981c74fcd13630a811ada98e8743d Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 19 Mar 2020 18:12:09 +0300
Subject: [PATCH 28/87] gostr341001: support unwrapped private keys support
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 <dbaryshkov@gmail.com>
---
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 703d64070..bfd81faa1 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 = &ASN1_OCTET_STRING_it,
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(MASKED_GOST_KEY, public_key),
+ .field_name = "public_key",
+ .item = &ASN1_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,
+ &MASKED_GOST_KEY_it);
+}
+
+int
+i2d_MASKED_GOST_KEY(MASKED_GOST_KEY *a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *)a, out, &MASKED_GOST_KEY_it);
+}
+
+MASKED_GOST_KEY *
+MASKED_GOST_KEY_new(void)
+{
+ return (MASKED_GOST_KEY *)ASN1_item_new(&MASKED_GOST_KEY_it);
+}
+
+void
+MASKED_GOST_KEY_free(MASKED_GOST_KEY *a)
+{
+ ASN1_item_free((ASN1_VALUE *)a, &MASKED_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 7cabfc79c..cdbda7b98 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 7cb70ed42..880c17cea 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;
+
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+
+ BN_free(pknum_masked);
+ return NULL;
+}
+
static int
priv_decode_gost01(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf)
{
@@ -450,6 +514,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(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0) {
GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
@@ -467,29 +532,61 @@ 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, &p, 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 {
- priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
- if (priv_key == NULL)
+ } else if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == *p) {
+ /* New format - Structure with masked private and separate public key */
+ MASKED_GOST_KEY *s =
+ d2i_MASKED_GOST_KEY(NULL, &p, priv_len);
+
+ if (s == NULL ||
+ !s->masked_priv_key ||
+ s->masked_priv_key->length % expected_key_len != 0) {
+ EVPerror(EVP_R_DECODE_ERROR);
+ MASKED_GOST_KEY_free(s);
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);
+ }
+
+ pk_num = unmask_priv_key(pk, s->masked_priv_key->data,
+ expected_key_len,
+ s->masked_priv_key->length / expected_key_len - 1);
+ MASKED_GOST_KEY_free(s);
+ } else if (V_ASN1_INTEGER == *p) {
+ priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
+ if (priv_key == NULL) {
+ EVPerror(EVP_R_DECODE_ERROR);
return 0;
}
+ pk_num = ASN1_INTEGER_to_BN(priv_key, NULL);
+ ASN1_INTEGER_free(priv_key);
+ } else {
+ EVPerror(EVP_R_DECODE_ERROR);
+ return 0;
+ }
+
+ if (pk_num == NULL) {
+ EVPerror(EVP_R_DECODE_ERROR);
+ return 0;
}
ec = pk->pkey.gost;
--
2.17.1

View file

@ -0,0 +1,109 @@
From 63d60fe4403982e7491286b9e1e47c0a4a9ed4d5 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 13:31:41 +0300
Subject: [PATCH 29/87] pkcs12: add support for GOST PFX files
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 <dbaryshkov@gmail.com>
---
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 d419a9d83..9a5297a23 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(&ctx);
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 f3132ec75..023bbbd92 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(&hmac);
if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) ||
diff --git a/src/lib/libcrypto/pkcs12/pkcs12.h b/src/lib/libcrypto/pkcs12/pkcs12.h
index 56635f9d7..4dab109bb 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.17.1

View file

@ -0,0 +1,750 @@
From ea7314c1d00c3d63636dd769f0cec60b7e42e79d Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 20 Mar 2020 00:39:56 +0300
Subject: [PATCH 30/87] modes: add functions implementing common code for
64-bit ciphers
64-bit ciphers are old, but it would be good to use common code for
their implementations.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
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 000000000..ec65ac5d3
--- /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-core@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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#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) {
+ for(n=0; n<8 && n<len; ++n)
+ out[n] = in[n] ^ iv[n];
+ for(; n<8; ++n)
+ out[n] = iv[n];
+ (*block)(out, out, key);
+ iv = out;
+ if (len<=8) break;
+ len -= 8;
+ in += 8;
+ out += 8;
+ }
+ memcpy(ivec,iv,8);
+}
+
+void CRYPTO_cbc64_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], block64_f block)
+{
+ size_t n;
+ union { size_t t[8/sizeof(size_t)]; unsigned char c[8]; } tmp;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (in != out) {
+ const unsigned char *iv = ivec;
+
+ if (STRICT_ALIGNMENT &&
+ ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+ while (len>=8) {
+ (*block)(in, out, key);
+ for(n=0; n<8; ++n)
+ out[n] ^= iv[n];
+ iv = in;
+ len -= 8;
+ in += 8;
+ out += 8;
+ }
+ } else if (8%sizeof(size_t) == 0) { /* always true */
+ while (len>=8) {
+ size_t *out_t=(size_t *)out, *iv_t=(size_t *)iv;
+
+ (*block)(in, out, key);
+ for(n=0; n<8/sizeof(size_t); n++)
+ out_t[n] ^= iv_t[n];
+ iv = in;
+ len -= 8;
+ in += 8;
+ out += 8;
+ }
+ }
+ memcpy(ivec,iv,8);
+ } else {
+ if (STRICT_ALIGNMENT &&
+ ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+ unsigned char c;
+ while (len>=8) {
+ (*block)(in, tmp.c, key);
+ for(n=0; n<8; ++n) {
+ c = in[n];
+ out[n] = tmp.c[n] ^ ivec[n];
+ ivec[n] = c;
+ }
+ len -= 8;
+ in += 8;
+ out += 8;
+ }
+ } else if (8%sizeof(size_t) == 0) { /* always true */
+ while (len>=8) {
+ size_t c, *out_t=(size_t *)out, *ivec_t=(size_t *)ivec;
+ const size_t *in_t=(const size_t *)in;
+
+ (*block)(in, tmp.c, key);
+ for(n=0; n<8/sizeof(size_t); n++) {
+ c = in_t[n];
+ out_t[n] = tmp.t[n] ^ ivec_t[n];
+ ivec_t[n] = c;
+ }
+ len -= 8;
+ in += 8;
+ out += 8;
+ }
+ }
+ }
+#endif
+ while (len) {
+ unsigned char c;
+ (*block)(in, tmp.c, key);
+ for(n=0; n<8 && n<len; ++n) {
+ c = in[n];
+ out[n] = tmp.c[n] ^ ivec[n];
+ ivec[n] = c;
+ }
+ if (len<=8) {
+ for (; n<8; ++n)
+ ivec[n] = in[n];
+ break;
+ }
+ len -= 8;
+ in += 8;
+ out += 8;
+ }
+}
diff --git a/src/lib/libcrypto/modes/cfb64.c b/src/lib/libcrypto/modes/cfb64.c
new file mode 100644
index 000000000..f335fa39c
--- /dev/null
+++ b/src/lib/libcrypto/modes/cfb64.c
@@ -0,0 +1,169 @@
+/* $OpenBSD: cfb64.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-core@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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used. The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void CRYPTO_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], int *num,
+ int enc, block64_f block)
+{
+ 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) {
+ (*block)(ivec, 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) {
+ (*block)(ivec, 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<len) {
+ if (n == 0) {
+ (*block)(ivec, ivec, key);
+ }
+ out[l] = ivec[n] ^= in[l];
+ ++l;
+ n = (n+1) % 8;
+ }
+ *num = n;
+ } else {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (8%sizeof(size_t) == 0) do { /* always true actually */
+ while (n && len) {
+ unsigned char c;
+ *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
+ --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) {
+ (*block)(ivec, 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) {
+ (*block)(ivec, 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) {
+ (*block)(ivec, ivec, key);
+ }
+ out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
+ ++l;
+ n = (n+1) % 8;
+ }
+ *num=n;
+ }
+}
diff --git a/src/lib/libcrypto/modes/ctr64.c b/src/lib/libcrypto/modes/ctr64.c
new file mode 100644
index 000000000..e1743cb91
--- /dev/null
+++ b/src/lib/libcrypto/modes/ctr64.c
@@ -0,0 +1,174 @@
+/* $OpenBSD: ctr64.c,v 1.7 2017/08/13 17:46:24 bcook 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-core@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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+/* NOTE: the IV/counter CTR mode is big-endian. The code itself
+ * is endian-neutral. */
+
+/* increment counter (64-bit int) by 1 */
+static void ctr64_inc(unsigned char *counter) {
+ u32 n=8;
+ u8 c;
+
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c) return;
+ } while (n);
+}
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+static void
+ctr64_inc_aligned(unsigned char *counter)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ ctr64_inc(counter);
+#else
+ size_t *data, c, n;
+ data = (size_t *)counter;
+ n = 8 / sizeof(size_t);
+ do {
+ --n;
+ c = data[n];
+ ++c;
+ data[n] = c;
+ if (c)
+ return;
+ } while (n);
+#endif
+}
+#endif
+
+/* The input encrypted as though 64bit counter mode is being
+ * used. The extra state information to record how much of the
+ * 64bit block we have used is contained in *num, and the
+ * encrypted counter is kept in ecount_buf. Both *num and
+ * ecount_buf must be initialised with zeros before the first
+ * call to CRYPTO_ctr64_encrypt().
+ *
+ * This algorithm assumes that the counter is in the x lower bits
+ * of the IV (ivec), and that the application has full control over
+ * overflow and the rest of the IV. This implementation takes NO
+ * responsability for checking that the counter doesn't overflow
+ * into the rest of the IV when incremented.
+ */
+void CRYPTO_ctr64_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], unsigned char ecount_buf[8],
+ unsigned int *num, block64_f block)
+{
+ unsigned int n;
+ size_t l=0;
+
+ assert(*num < 8);
+
+ n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (8%sizeof(size_t) == 0) do { /* always true actually */
+ while (n && len) {
+ *(out++) = *(in++) ^ ecount_buf[n];
+ --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) {
+ (*block)(ivec, ecount_buf, key);
+ ctr64_inc_aligned(ivec);
+ for (; n<8; n+=sizeof(size_t))
+ *(size_t *)(out+n) =
+ *(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n);
+ len -= 8;
+ out += 8;
+ in += 8;
+ n = 0;
+ }
+ if (len) {
+ (*block)(ivec, ecount_buf, key);
+ ctr64_inc_aligned(ivec);
+ while (len--) {
+ out[n] = in[n] ^ ecount_buf[n];
+ ++n;
+ }
+ }
+ *num = n;
+ return;
+ } while(0);
+ /* the rest would be commonly eliminated by x86* compiler */
+#endif
+ while (l<len) {
+ if (n==0) {
+ (*block)(ivec, ecount_buf, key);
+ ctr64_inc(ivec);
+ }
+ out[l] = in[l] ^ ecount_buf[n];
+ ++l;
+ n = (n+1) % 8;
+ }
+
+ *num=n;
+}
diff --git a/src/lib/libcrypto/modes/modes.h b/src/lib/libcrypto/modes/modes.h
index 67ec7518d..2344e944e 100644
--- a/src/lib/libcrypto/modes/modes.h
+++ b/src/lib/libcrypto/modes/modes.h
@@ -139,6 +139,32 @@ typedef struct xts128_context XTS128_CONTEXT;
int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
const unsigned char *inp, unsigned char *out, size_t len, int enc);
+typedef void (*block64_f)(const unsigned char in[8],
+ unsigned char out[8],
+ const void *key);
+
+void CRYPTO_cbc64_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], block64_f block);
+void CRYPTO_cbc64_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], block64_f block);
+
+void CRYPTO_ctr64_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], unsigned char ecount_buf[8],
+ unsigned int *num, block64_f block);
+
+void CRYPTO_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], int *num,
+ block64_f block);
+
+void CRYPTO_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], int *num,
+ int enc, block64_f block);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/libcrypto/modes/ofb64.c b/src/lib/libcrypto/modes/ofb64.c
new file mode 100644
index 000000000..8368811ce
--- /dev/null
+++ b/src/lib/libcrypto/modes/ofb64.c
@@ -0,0 +1,119 @@
+/* $OpenBSD: ofb64.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-core@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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used. The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void CRYPTO_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[8], int *num,
+ block64_f block)
+{
+ unsigned int n;
+ size_t l=0;
+
+ n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+ if (8%sizeof(size_t) == 0) do { /* always true actually */
+ while (n && len) {
+ *(out++) = *(in++) ^ ivec[n];
+ --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) {
+ (*block)(ivec, ivec, key);
+ for (; n<8; n+=sizeof(size_t))
+ *(size_t*)(out+n) =
+ *(size_t*)(in+n) ^ *(size_t*)(ivec+n);
+ len -= 8;
+ out += 8;
+ in += 8;
+ n = 0;
+ }
+ if (len) {
+ (*block)(ivec, ivec, key);
+ while (len--) {
+ out[n] = in[n] ^ ivec[n];
+ ++n;
+ }
+ }
+ *num = n;
+ return;
+ } while(0);
+ /* the rest would be commonly eliminated by x86* compiler */
+#endif
+ while (l<len) {
+ if (n==0) {
+ (*block)(ivec, ivec, key);
+ }
+ out[l] = in[l] ^ ivec[n];
+ ++l;
+ n = (n+1) % 8;
+ }
+
+ *num=n;
+}
--
2.17.1

View file

@ -0,0 +1,185 @@
From 9ccc19763e8020f1a760521c269fc561741b2aaf Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Mon, 23 Mar 2020 22:53:46 +0300
Subject: [PATCH 31/87] gost: drop key_len from Gost28147_set_key
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 <dbaryshkov@gmail.com>
---
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 730de4fed..e3c608f0e 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(&c->ks, key, ctx->key_len * 8);
+ Gost2814789_set_key(&c->ks, key);
+
+ return 1;
}
int
diff --git a/src/lib/libcrypto/evp/m_gost2814789.c b/src/lib/libcrypto/evp/m_gost2814789.c
index 279af872e..779ccf07d 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(&gctx->cipher, p2, p1);
+ Gost2814789_set_key(&gctx->cipher, p2);
+ return 1;
case EVP_MD_CTRL_GOST_SET_SBOX:
return Gost2814789_set_sbox(&gctx->cipher, p1);
}
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index 092f96fb6..b6e5b51c4 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 e285413ed..5016ed004 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(&c, nid);
memcpy(c.mac, iv, 8);
- Gost2814789_set_key(&c.cipher, key, 256);
+ Gost2814789_set_key(&c.cipher, key);
GOST2814789IMIT_Update(&c, d, n);
GOST2814789IMIT_Final(md, &c);
explicit_bzero(&c, sizeof(c));
diff --git a/src/lib/libcrypto/gost/gost89_keywrap.c b/src/lib/libcrypto/gost/gost89_keywrap.c
index a754c4d56..47a11ad0c 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,
&mask, 1);
@@ -102,7 +102,7 @@ gost_key_wrap_crypto_pro(int nid, const unsigned char *keyExchangeKey,
Gost2814789_set_sbox(&ctx, nid);
key_diversify_crypto_pro(&ctx, keyExchangeKey, ukm, kek_ukm);
- Gost2814789_set_key(&ctx, kek_ukm, 256);
+ Gost2814789_set_key(&ctx, kek_ukm);
memcpy(wrappedKey, ukm, 8);
Gost2814789_encrypt(sessionKey + 0, wrappedKey + 8 + 0, &ctx);
Gost2814789_encrypt(sessionKey + 8, wrappedKey + 8 + 8, &ctx);
@@ -122,7 +122,7 @@ gost_key_unwrap_crypto_pro(int nid, const unsigned char *keyExchangeKey,
Gost2814789_set_sbox(&ctx, nid);
/* First 8 bytes of wrapped Key is ukm */
key_diversify_crypto_pro(&ctx, keyExchangeKey, wrappedKey, kek_ukm);
- Gost2814789_set_key(&ctx, kek_ukm, 256);
+ Gost2814789_set_key(&ctx, kek_ukm);
Gost2814789_decrypt(wrappedKey + 8 + 0, sessionKey + 0, &ctx);
Gost2814789_decrypt(wrappedKey + 8 + 8, sessionKey + 8, &ctx);
Gost2814789_decrypt(wrappedKey + 8 + 16, sessionKey + 16, &ctx);
diff --git a/src/lib/libcrypto/gost/gost89_params.c b/src/lib/libcrypto/gost/gost89_params.c
index 35d8f62fe..526710cb0 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_set_key(GOST2814789_KEY *key, const unsigned char *userKey,
- const int bits)
+void
+Gost2814789_set_key(GOST2814789_KEY *key, const unsigned char *userKey)
{
int i;
- if (bits != 256)
- return 0;
-
for (i = 0; i < 8; i++)
c2l(userKey, key->key[i]);
key->count = 0;
-
- return 1;
}
void
@@ -239,6 +233,6 @@ Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key)
Gost2814789_decrypt(CryptoProKeyMeshingKey + 16, newkey + 16, key);
Gost2814789_decrypt(CryptoProKeyMeshingKey + 24, newkey + 24, key);
- Gost2814789_set_key(key, newkey, 256);
+ Gost2814789_set_key(key, newkey);
}
#endif
diff --git a/src/lib/libcrypto/gost/gostr341194.c b/src/lib/libcrypto/gost/gostr341194.c
index 2a462185a..9b750efd6 100644
--- a/src/lib/libcrypto/gost/gostr341194.c
+++ b/src/lib/libcrypto/gost/gostr341194.c
@@ -139,7 +139,7 @@ hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M)
xor_blocks(W, H, M, 32);
swap_bytes(W, Key);
/* Encrypt first 8 bytes of H with first key */
- Gost2814789_set_key(&c->cipher, Key, 256);
+ Gost2814789_set_key(&c->cipher, Key);
Gost2814789_encrypt(H, S, &c->cipher);
/* Compute second key */
@@ -149,7 +149,7 @@ hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M)
xor_blocks(W, U, V, 32);
swap_bytes(W, Key);
/* encrypt second 8 bytes of H with second key */
- Gost2814789_set_key(&c->cipher, Key, 256);
+ Gost2814789_set_key(&c->cipher, Key);
Gost2814789_encrypt(H+8, S+8, &c->cipher);
/* compute third key */
@@ -175,7 +175,7 @@ hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M)
xor_blocks(W, U, V, 32);
swap_bytes(W, Key);
/* encrypt third 8 bytes of H with third key */
- Gost2814789_set_key(&c->cipher, Key, 256);
+ Gost2814789_set_key(&c->cipher, Key);
Gost2814789_encrypt(H+16, S+16, &c->cipher);
/* Compute fourth key */
@@ -185,7 +185,7 @@ hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M)
xor_blocks(W, U, V, 32);
swap_bytes(W, Key);
/* Encrypt last 8 bytes with fourth key */
- Gost2814789_set_key(&c->cipher, Key, 256);
+ Gost2814789_set_key(&c->cipher, Key);
Gost2814789_encrypt(H+24, S+24, &c->cipher);
for (i = 0; i < 12; i++)
--
2.17.1

View file

@ -0,0 +1,84 @@
From 62e85837c5b1979ab96800d6f91ff2708d5e984c Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Mon, 23 Mar 2020 23:55:07 +0300
Subject: [PATCH 32/87] gost: use key_meshing for specifying section size
In preparation to adding ACPKM support, switch key_meshing to be a
section size rather than just a flag.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
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 b6e5b51c4..a9ed5a1c5 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 5016ed004..e5c7f6a2b 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 526710cb0..c454fd7af 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.17.1

View file

@ -0,0 +1,468 @@
From 585ab77911db9b4ed588cd20cc03abec20390501 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 20 Mar 2020 01:11:59 +0300
Subject: [PATCH 33/87] gost: add support for magma cipher
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 <dbaryshkov@gmail.com>
---
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 | 11 ++
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, 314 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 662eb4dc2..6102af2f8 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 9e9d39d5a..59342beb7 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 000000000..712f79278
--- /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 <dbaryshkov@gmail.com>
+ *
+ * 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 <string.h>
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_GOST
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/modes.h>
+#include <openssl/gost.h>
+#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(&c->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, unsigned char *ivec, int *num)
+{
+ CRYPTO_ofb64_encrypt(in, out, length, key, ivec, num,
+ (block64_f)Magma_encrypt);
+}
+
+static int
+magma_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+ size_t len)
+{
+ EVP_MAGMA_CTX *key = EVP_C_DATA(EVP_MAGMA_CTX, ctx);
+
+ CRYPTO_ctr64_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_encrypt);
+ return 1;
+}
+
+IMPLEMENT_BLOCK_CIPHER(magma, ks, Magma, EVP_MAGMA_CTX,
+ NID_magma, 8, 32, 8, 64, 0, magma_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ magma_ctl)
+
+BLOCK_CIPHER_def1(magma, ctr, ctr, CTR, EVP_MAGMA_CTX,
+ NID_magma, 1, 32, 4, 0,
+ magma_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ magma_ctl)
+
+#endif
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index f1fe8a1e3..63d4e41a7 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -846,6 +846,11 @@ const EVP_CIPHER *EVP_chacha20(void);
const EVP_CIPHER *EVP_gost2814789_ecb(void);
const EVP_CIPHER *EVP_gost2814789_cfb64(void);
const EVP_CIPHER *EVP_gost2814789_cnt(void);
+const EVP_CIPHER *EVP_magma_ecb(void);
+const EVP_CIPHER *EVP_magma_cbc(void);
+const EVP_CIPHER *EVP_magma_cfb64(void);
+const EVP_CIPHER *EVP_magma_ofb(void);
+const EVP_CIPHER *EVP_magma_ctr(void);
#endif
#ifndef OPENSSL_NO_SM4
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index a9ed5a1c5..d584a55f3 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -83,6 +83,35 @@ void Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out,
size_t length, GOST2814789_KEY *key,
unsigned char *ivec, unsigned char *cnt_buf, int *num);
+#define MAGMA_KEY GOST2814789_KEY
+
+void Magma_set_key(MAGMA_KEY *key, const unsigned char *userKey);
+
+void Magma_encrypt(const unsigned char *in, unsigned char *out,
+ const MAGMA_KEY *key);
+void Magma_decrypt(const unsigned char *in, unsigned char *out,
+ const MAGMA_KEY *key);
+
+#define KUZNYECHIK_KEY_SIZE 32
+#define KUZNYECHIK_SUBKEYS_SIZE (16 * 10)
+#define KUZNYECHIK_BLOCK_SIZE 16
+
+typedef struct kuznyechik_key_st
+{
+ unsigned char key[KUZNYECHIK_SUBKEYS_SIZE];
+ unsigned int count;
+ unsigned int key_meshing;
+} KUZNYECHIK_KEY;
+
+void Kuznyechik_set_key(KUZNYECHIK_KEY *key, const unsigned char *userKey, int enc);
+
+void Kuznyechik_encrypt(const unsigned char *in, unsigned char *out,
+ const KUZNYECHIK_KEY *key);
+void Kuznyechik_decrypt(const unsigned char *in, unsigned char *out,
+ const KUZNYECHIK_KEY *key);
+void Kuznyechik_acpkm_encrypt(const unsigned char *in, unsigned char *out,
+ KUZNYECHIK_KEY *key);
+
typedef struct {
ASN1_OCTET_STRING *iv;
ASN1_OBJECT *enc_param_set;
diff --git a/src/lib/libcrypto/gost/gost2814789.c b/src/lib/libcrypto/gost/gost2814789.c
index e5c7f6a2b..c9deee695 100644
--- a/src/lib/libcrypto/gost/gost2814789.c
+++ b/src/lib/libcrypto/gost/gost2814789.c
@@ -1,8 +1,11 @@
/* $OpenBSD: gost2814789.c,v 1.5 2015/09/10 15:56:25 jsing Exp $ */
/*
+ * Copyright (c) 2020 Dmitry Baryshkov <dbaryshkov@gmail.com>
* Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
* Copyright (c) 2005-2006 Cryptocom LTD
*
+ * Magma support sponsored by ROSA Linux
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -134,6 +137,74 @@ Gost2814789_decrypt(const unsigned char *in, unsigned char *out,
l2c(n1, out);
}
+void
+Magma_encrypt(const unsigned char *in, unsigned char *out,
+ const MAGMA_KEY *key)
+{
+ unsigned int n1, n2; /* As named in the GOST */
+
+ be_c2l(in, n2);
+ be_c2l(in, n1);
+
+ /* Instead of swapping halves, swap names each round */
+ n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+ n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+ n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+ n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+ n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+ n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+ n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+ n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+ n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+ n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+ n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+ n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+ n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
+ n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
+ n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
+ n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
+
+ be_l2c(n1, out);
+ be_l2c(n2, out);
+}
+
+void
+Magma_decrypt(const unsigned char *in, unsigned char *out,
+ const MAGMA_KEY *key)
+{
+ unsigned int n1, n2; /* As named in the GOST */
+
+ be_c2l(in, n2);
+ be_c2l(in, n1);
+
+ /* Instead of swapping halves, swap names each round */
+ n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+ n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+ n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+ n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+ n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
+ n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
+ n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
+ n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
+
+ n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
+ n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
+ n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
+ n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
+
+ n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
+ n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
+ n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
+ n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
+
+ be_l2c(n1, out);
+ be_l2c(n2, out);
+}
+
static void
Gost2814789_mac(const unsigned char *in, unsigned char *mac,
GOST2814789_KEY *key)
diff --git a/src/lib/libcrypto/gost/gost89_params.c b/src/lib/libcrypto/gost/gost89_params.c
index c454fd7af..7365f7a43 100644
--- a/src/lib/libcrypto/gost/gost89_params.c
+++ b/src/lib/libcrypto/gost/gost89_params.c
@@ -223,6 +223,30 @@ Gost2814789_set_key(GOST2814789_KEY *key, const unsigned char *userKey)
key->count = 0;
}
+void
+Magma_set_key_int(MAGMA_KEY *key, const unsigned char *userKey)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ be_c2l(userKey, key->key[i]);
+
+ key->count = 0;
+}
+
+void
+Magma_set_key(MAGMA_KEY *key, const unsigned char *userKey)
+{
+ unsigned int km = key->key_meshing;
+
+ /* Preserve key meshing setting around setting sbox */
+ Gost2814789_set_sbox(key, NID_id_tc26_gost_28147_param_Z);
+
+ key->key_meshing = km;
+
+ Magma_set_key_int(key, userKey);
+}
+
void
Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key)
{
diff --git a/src/lib/libcrypto/gost/gost_locl.h b/src/lib/libcrypto/gost/gost_locl.h
index b2e2c1362..302a19c5c 100644
--- a/src/lib/libcrypto/gost/gost_locl.h
+++ b/src/lib/libcrypto/gost/gost_locl.h
@@ -83,12 +83,23 @@ typedef struct {
*((c)++)=(unsigned char)(((l)>>24)&0xff))
#endif
+#define be_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++))) ))
+#define be_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
extern void Gost2814789_encrypt(const unsigned char *in, unsigned char *out,
const GOST2814789_KEY *key);
extern void Gost2814789_decrypt(const unsigned char *in, unsigned char *out,
const GOST2814789_KEY *key);
extern void Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key);
+void Magma_set_key_int(MAGMA_KEY *key, const unsigned char *userKey);
+
/* GOST 28147-89 key wrapping */
extern int gost_key_unwrap_crypto_pro(int nid,
const unsigned char *keyExchangeKey, const unsigned char *wrappedKey,
diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num
index ba75ec246..fa5914ada 100644
--- a/src/lib/libcrypto/objects/obj_mac.num
+++ b/src/lib/libcrypto/objects/obj_mac.num
@@ -998,3 +998,12 @@ 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
+magma_ecb 1001
+magma_cbc 1002
+magma_cfb64 1003
+magma_ofb64 1004
+magma_ctr 1005
+id_tc26_cipher_gostr3412_2015_magma_ctracpkm 1006
+id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac 1007
+id_tc26_cipher_gostr3412_2015_magma_mgm 1008
+magma_mac 1009
diff --git a/src/lib/libcrypto/objects/objects.txt b/src/lib/libcrypto/objects/objects.txt
index 8e533530f..2dbd8575d 100644
--- a/src/lib/libcrypto/objects/objects.txt
+++ b/src/lib/libcrypto/objects/objects.txt
@@ -1388,6 +1388,20 @@ tc26 1 1 2 : id-tc26-gost3410-2012-512 : GOST R 34.10-2012 (512 bit)
tc26 1 3 2 : id-tc26-signwithdigest-gost3410-2012-256 : GOST R 34.11-2012 with GOST R 34.10-2012 (256 bit)
tc26 1 3 3 : id-tc26-signwithdigest-gost3410-2012-512 : GOST R 34.11-2012 with GOST R 34.10-2012 (512 bit)
+#GOST R 34.12-2014, cipher Magma
+ : magma-ecb
+ : magma-cbc
+ : magma-cfb64
+ : magma-ofb64
+ : magma-ctr
+!Cname id-tc26-cipher-gostr3412-2015-magma-ctracpkm
+tc26 1 5 1 1 : magma-ctr-acpkm
+!Cname id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac
+tc26 1 5 1 2 : magma-ctr-acpkm-omac
+!Cname id-tc26-cipher-gostr3412-2015-magma-mgm
+tc26 1 5 1 3 : magma-mgm
+ : magma-mac
+
# Curves from draft-ietf-curdle-pkix-02
1 3 101 110 : X25519
1 3 101 111 : X448
diff --git a/src/regress/lib/libcrypto/evp/evptests.txt b/src/regress/lib/libcrypto/evp/evptests.txt
index 2a5806526..8b4739276 100644
--- a/src/regress/lib/libcrypto/evp/evptests.txt
+++ b/src/regress/lib/libcrypto/evp/evptests.txt
@@ -382,3 +382,21 @@ ChaCha:5555555555555555555555555555555555555555555555555555555555555555:00000000
ChaCha:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:0000000000000000aaaaaaaaaaaaaaaa0000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:9aa2a9f656efde5aa7591c5fed4b35aea2895dec7cb4543b9e9f21f5e7bcbcf3c43c748a970888f8248393a09d43e0b7e164bc4d0b0fb240a2d72115c4808906:1
ChaCha:00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100:00000000000000000f1e2d3c4b5a69780000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:9fadf409c00811d00431d67efbd88fba59218d5d6708b1d685863fabbb0e961eea480fd6fb532bfd494b2151015057423ab60a63fe4f55f7a212e2167ccab931:1
ChaCha:c46ec1b18ce8a878725a37e780dfb7351f68ed2e194c79fbc6aebee1a667975d:00000000000000001ada31d5cf6882210000000000000000:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f63a89b75c2271f9368816542ba52f06ed49241792302b00b5e8f80ae9a473afc25b218f519af0fdd406362e8d69de7f54c604a6e00f353f110f771bdca8ab92:1
+
+#GOST R 34.12-2015 test vectors
+magma-ecb:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff::fedcba9876543210:4ee901e5c2d8ca3d:1
+magma-ecb:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff::fedcba9876543210:4ee901e5c2d8ca3d:0
+
+#GOST R 34.13-2015 test vectors
+magma-ecb:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff::92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:2b073f0494f372a0de70e715d3556e4811d8d9e9eacfbc1e7c68260996c67efb:1
+magma-ecb:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff::92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:2b073f0494f372a0de70e715d3556e4811d8d9e9eacfbc1e7c68260996c67efb:0
+magma-ctr:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:12345678:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:4e98110c97b7b93c3e250d93d6e85d69136d868807b2dbef568eb680ab52a12d:1
+magma-ctr:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:12345678:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:4e98110c97b7b93c3e250d93d6e85d69136d868807b2dbef568eb680ab52a12d:0
+
+# Manually
+magma-cbc:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:96d1b05eea683919f396b78c1d47bb616183e2cca976a4babe9ce87d6fa73cf2:1
+magma-cbc:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:96d1b05eea683919f396b78c1d47bb616183e2cca976a4babe9ce87d6fa73cf2:0
+magma-ofb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:db37e0e266903c8331340c48dcbead127193f8746455692c527d38b4e3feedd2:1
+magma-ofb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:db37e0e266903c8331340c48dcbead127193f8746455692c527d38b4e3feedd2:0
+magma-cfb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:db37e0e266903c83b571ee29cca54ce791fabcb3abbe2fe3ff5d972d770f6ae9:1
+magma-cfb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:db37e0e266903c83b571ee29cca54ce791fabcb3abbe2fe3ff5d972d770f6ae9:0
--
2.17.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,52 @@
From f8edb0a765f94a97418247a5e4dd0f289637838b Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 17 Apr 2020 23:07:07 +0300
Subject: [PATCH 35/87] kuznyechik: fix IV handling for CTR mode
kuznyechik-ctr uses half length IV per the specification, which is
handled correctly. However we still have to zero the second half of IV.
Do so in ctr_init_key() callback.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/e_kuznyechik.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/lib/libcrypto/evp/e_kuznyechik.c b/src/lib/libcrypto/evp/e_kuznyechik.c
index 7ac5ed7a6..ebb857c62 100644
--- a/src/lib/libcrypto/evp/e_kuznyechik.c
+++ b/src/lib/libcrypto/evp/e_kuznyechik.c
@@ -102,6 +102,19 @@ Kuznyechik_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t le
(block128_f)Kuznyechik_encrypt);
}
+static int
+kuznyechik_ctr_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ if (iv)
+ memset(ctx->iv + 8, 0, 8);
+
+ if (!key)
+ return 1;
+
+ return kuznyechik_init_key(ctx, key, iv, enc);
+}
+
static int
kuznyechik_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
size_t len)
@@ -120,8 +133,8 @@ IMPLEMENT_BLOCK_CIPHER(kuznyechik, ks, Kuznyechik, EVP_KUZNYECHIK_CTX,
kuznyechik_ctl)
BLOCK_CIPHER_def1(kuznyechik, ctr, ctr, CTR, EVP_KUZNYECHIK_CTX,
- NID_kuznyechik, 1, 32, 8, 0,
- kuznyechik_init_key, NULL,
+ NID_kuznyechik, 1, 32, 8, EVP_CIPH_ALWAYS_CALL_INIT,
+ kuznyechik_ctr_init_key, NULL,
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
kuznyechik_ctl)
--
2.17.1

View file

@ -0,0 +1,52 @@
From 0f87b92f702c83c1cc18798d1b05b9aacd8ce186 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 17 Apr 2020 23:07:07 +0300
Subject: [PATCH 36/87] magma: fix IV handling for CTR mode
magma-ctr uses half length IV per the specification, which is
handled correctly. However we still have to zero the second half of IV.
Do so in ctr_init_key() callback.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/e_magma.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/lib/libcrypto/evp/e_magma.c b/src/lib/libcrypto/evp/e_magma.c
index 712f79278..c88b25827 100644
--- a/src/lib/libcrypto/evp/e_magma.c
+++ b/src/lib/libcrypto/evp/e_magma.c
@@ -96,6 +96,19 @@ Magma_ofb64_encrypt(const unsigned char *in, unsigned char *out, size_t length,
(block64_f)Magma_encrypt);
}
+static int
+magma_ctr_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ if (iv)
+ memset(ctx->iv + 4, 0, 4);
+
+ if (!key)
+ return 1;
+
+ return magma_init_key(ctx, key, iv, enc);
+}
+
static int
magma_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
size_t len)
@@ -114,8 +127,8 @@ IMPLEMENT_BLOCK_CIPHER(magma, ks, Magma, EVP_MAGMA_CTX,
magma_ctl)
BLOCK_CIPHER_def1(magma, ctr, ctr, CTR, EVP_MAGMA_CTX,
- NID_magma, 1, 32, 4, 0,
- magma_init_key, NULL,
+ NID_magma, 1, 32, 4, EVP_CIPH_ALWAYS_CALL_INIT,
+ magma_ctr_init_key, NULL,
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
magma_ctl)
--
2.17.1

View file

@ -0,0 +1,100 @@
From c982fe656b75adba6c64552d1657b842555cb887 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Mon, 23 Mar 2020 23:58:00 +0300
Subject: [PATCH 37/87] gost: add support for ACPKM rekeying
Add support for ACPKM internal rekeying (RFC 8645).
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/evp.h | 2 ++
src/lib/libcrypto/gost/gost89_params.c | 38 ++++++++++++++++++++++++++
src/lib/libcrypto/gost/gost_locl.h | 5 ++++
3 files changed, 45 insertions(+)
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 26e025d09..77b3a4f8e 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -396,6 +396,8 @@ struct evp_cipher_st {
#define EVP_CTRL_GCM_SET_IV_INV 0x18
/* Set the S-BOX NID for GOST ciphers */
#define EVP_CTRL_GOST_SET_SBOX 0x19
+/* Set the key meshing section for GOST ciphers */
+#define EVP_CTRL_GOST_SET_MESHING 0x1a
/* GCM TLS constants */
/* Length of fixed part of IV derived from PRF */
diff --git a/src/lib/libcrypto/gost/gost89_params.c b/src/lib/libcrypto/gost/gost89_params.c
index 7365f7a43..e02265389 100644
--- a/src/lib/libcrypto/gost/gost89_params.c
+++ b/src/lib/libcrypto/gost/gost89_params.c
@@ -50,6 +50,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include <openssl/opensslconf.h>
@@ -259,4 +260,41 @@ Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key)
Gost2814789_set_key(key, newkey);
}
+
+#define ACPKM_KEY_SIZE 128
+static unsigned char acpkm_mesh_data[ACPKM_KEY_SIZE] =
+{
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+
+
+void
+acpkm_key_mesh(void *ctx,
+ acpkm_block *block, acpkm_set_key *set_key,
+ unsigned int block_size, unsigned int key_size)
+{
+ unsigned int i;
+ unsigned char new_key[ACPKM_KEY_SIZE];
+
+ for (i = 0; i < key_size; i += block_size) {
+ block(&acpkm_mesh_data[i], &new_key[i], ctx);
+ }
+ set_key(ctx, new_key);
+ explicit_bzero(new_key, i);
+}
#endif
diff --git a/src/lib/libcrypto/gost/gost_locl.h b/src/lib/libcrypto/gost/gost_locl.h
index 302a19c5c..f512029e1 100644
--- a/src/lib/libcrypto/gost/gost_locl.h
+++ b/src/lib/libcrypto/gost/gost_locl.h
@@ -97,6 +97,11 @@ extern void Gost2814789_encrypt(const unsigned char *in, unsigned char *out,
extern void Gost2814789_decrypt(const unsigned char *in, unsigned char *out,
const GOST2814789_KEY *key);
extern void Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key);
+typedef void acpkm_block(const unsigned char *in, unsigned char *out, void *ctx);
+typedef void acpkm_set_key(void *ctx, const unsigned char *key);
+extern void acpkm_key_mesh(void *ctx,
+ acpkm_block *block, acpkm_set_key *set_key,
+ unsigned int block_size, unsigned int key_size);
void Magma_set_key_int(MAGMA_KEY *key, const unsigned char *userKey);
--
2.17.1

View file

@ -0,0 +1,202 @@
From c99092ce70c10a4786bed1094ba044ae0026759f Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sat, 4 Apr 2020 16:56:14 +0300
Subject: [PATCH 38/87] gost: add support for GOST 34.12 (Magma, Kuznyechik)
encryption params
Add encoding and decoding support for GOST 34.12 encryption params.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/gost/gost.h | 3 +
src/lib/libcrypto/gost/gost_asn1.c | 130 +++++++++++++++++++++++++++++
src/lib/libcrypto/gost/gost_asn1.h | 10 +++
3 files changed, 143 insertions(+)
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index 4fef765ce..421ca29f3 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -121,6 +121,9 @@ GOST_CIPHER_PARAMS *d2i_GOST_CIPHER_PARAMS(GOST_CIPHER_PARAMS **a, const unsigne
int i2d_GOST_CIPHER_PARAMS(GOST_CIPHER_PARAMS *a, unsigned char **out);
extern const ASN1_ITEM GOST_CIPHER_PARAMS_it;
+int gost3412_ctr_acpkm_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params, unsigned int il);
+int gost3412_ctr_acpkm_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params, unsigned int il);
+
#define GOST2814789IMIT_LENGTH 4
#define GOST2814789IMIT_CBLOCK 8
#define GOST2814789IMIT_LONG unsigned int
diff --git a/src/lib/libcrypto/gost/gost_asn1.c b/src/lib/libcrypto/gost/gost_asn1.c
index bfd81faa1..14e46afab 100644
--- a/src/lib/libcrypto/gost/gost_asn1.c
+++ b/src/lib/libcrypto/gost/gost_asn1.c
@@ -10,9 +10,12 @@
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_GOST
+#include <string.h>
+
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/gost.h>
+#include <openssl/err.h>
#include "gost_locl.h"
#include "gost_asn1.h"
@@ -344,4 +347,131 @@ GOST_CIPHER_PARAMS_free(GOST_CIPHER_PARAMS *a)
ASN1_item_free((ASN1_VALUE *)a, &GOST_CIPHER_PARAMS_it);
}
+static const ASN1_TEMPLATE GOST3412_ENCRYPTION_PARAMS_seq_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(GOST3412_ENCRYPTION_PARAMS, iv),
+ .field_name = "iv",
+ .item = &ASN1_OCTET_STRING_it,
+ },
+};
+
+const ASN1_ITEM GOST3412_ENCRYPTION_PARAMS_it = {
+ .itype = ASN1_ITYPE_NDEF_SEQUENCE,
+ .utype = V_ASN1_SEQUENCE,
+ .templates = GOST3412_ENCRYPTION_PARAMS_seq_tt,
+ .tcount = sizeof(GOST3412_ENCRYPTION_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE),
+ .funcs = NULL,
+ .size = sizeof(GOST3412_ENCRYPTION_PARAMS),
+ .sname = "GOST3412_ENCRYPTION_PARAMS",
+};
+
+GOST3412_ENCRYPTION_PARAMS *
+d2i_GOST3412_ENCRYPTION_PARAMS(GOST3412_ENCRYPTION_PARAMS **a, const unsigned char **in, long len)
+{
+ return (GOST3412_ENCRYPTION_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+ &GOST3412_ENCRYPTION_PARAMS_it);
+}
+
+int
+i2d_GOST3412_ENCRYPTION_PARAMS(GOST3412_ENCRYPTION_PARAMS *a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST3412_ENCRYPTION_PARAMS_it);
+}
+
+GOST3412_ENCRYPTION_PARAMS *
+GOST3412_ENCRYPTION_PARAMS_new(void)
+{
+ return (GOST3412_ENCRYPTION_PARAMS *)ASN1_item_new(&GOST3412_ENCRYPTION_PARAMS_it);
+}
+
+void
+GOST3412_ENCRYPTION_PARAMS_free(GOST3412_ENCRYPTION_PARAMS *a)
+{
+ ASN1_item_free((ASN1_VALUE *)a, &GOST3412_ENCRYPTION_PARAMS_it);
+}
+
+int
+gost3412_ctr_acpkm_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params, unsigned int il)
+{
+ int len = 0;
+ unsigned char *buf = NULL;
+ unsigned char *p = NULL;
+ GOST3412_ENCRYPTION_PARAMS *gcp = NULL;
+ ASN1_OCTET_STRING *os = NULL;
+
+ if (params == NULL)
+ return 0;
+
+ gcp = GOST3412_ENCRYPTION_PARAMS_new();
+ if (ASN1_OCTET_STRING_set(gcp->iv, NULL, il + 8) == 0) {
+ GOST3412_ENCRYPTION_PARAMS_free(gcp);
+ GOSTerror(ERR_R_ASN1_LIB);
+ return 0;
+ }
+
+ memcpy(gcp->iv->data, ctx->iv, il);
+ memcpy(gcp->iv->data + il, ctx->oiv, 8);
+
+ len = i2d_GOST3412_ENCRYPTION_PARAMS(gcp, NULL);
+ p = buf = malloc(len);
+ if (buf == NULL) {
+ GOST3412_ENCRYPTION_PARAMS_free(gcp);
+ GOSTerror(ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ i2d_GOST3412_ENCRYPTION_PARAMS(gcp, &p);
+ GOST3412_ENCRYPTION_PARAMS_free(gcp);
+
+ os = ASN1_OCTET_STRING_new();
+ if (os == NULL) {
+ free(buf);
+ GOSTerror(ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (ASN1_OCTET_STRING_set(os, buf, len) == 0) {
+ ASN1_OCTET_STRING_free(os);
+ free(buf);
+ GOSTerror(ERR_R_ASN1_LIB);
+ return 0;
+ }
+ free(buf);
+
+ ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
+
+ return 1;
+}
+
+int
+gost3412_ctr_acpkm_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params, unsigned int il)
+{
+ int len;
+ GOST3412_ENCRYPTION_PARAMS *gcp = NULL;
+ unsigned char *p;
+
+ if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
+ return -1;
+
+ p = params->value.sequence->data;
+
+ gcp = d2i_GOST3412_ENCRYPTION_PARAMS(NULL, (const unsigned char **)&p,
+ params->value.sequence->length);
+
+ len = gcp->iv->length;
+ if (len != il + 8 || len > sizeof(ctx->iv)) {
+ GOST3412_ENCRYPTION_PARAMS_free(gcp);
+ GOSTerror(GOST_R_INVALID_IV_LENGTH);
+ return -1;
+ }
+
+ memcpy(ctx->iv, gcp->iv->data, il);
+ memset(ctx->iv + il, 0, EVP_MAX_IV_LENGTH - il);
+ memcpy(ctx->oiv, gcp->iv->data + il, 8);
+
+ GOST3412_ENCRYPTION_PARAMS_free(gcp);
+
+ return 1;
+}
+
#endif
diff --git a/src/lib/libcrypto/gost/gost_asn1.h b/src/lib/libcrypto/gost/gost_asn1.h
index cdbda7b98..5af16e00e 100644
--- a/src/lib/libcrypto/gost/gost_asn1.h
+++ b/src/lib/libcrypto/gost/gost_asn1.h
@@ -113,6 +113,16 @@ GOST_KEY_PARAMS *d2i_GOST_KEY_PARAMS(GOST_KEY_PARAMS **a, const unsigned char **
int i2d_GOST_KEY_PARAMS(GOST_KEY_PARAMS *a, unsigned char **out);
extern const ASN1_ITEM GOST_KEY_PARAMS_it;
+typedef struct {
+ ASN1_OCTET_STRING *iv;
+} GOST3412_ENCRYPTION_PARAMS;
+
+GOST3412_ENCRYPTION_PARAMS *GOST3412_ENCRYPTION_PARAMS_new(void);
+void GOST3412_ENCRYPTION_PARAMS_free(GOST3412_ENCRYPTION_PARAMS *a);
+GOST3412_ENCRYPTION_PARAMS *d2i_GOST3412_ENCRYPTION_PARAMS(GOST3412_ENCRYPTION_PARAMS **a, const unsigned char **in, long len);
+int i2d_GOST3412_ENCRYPTION_PARAMS(GOST3412_ENCRYPTION_PARAMS *a, unsigned char **out);
+extern const ASN1_ITEM GOST3412_ENCRYPTION_PARAMS_it;
+
__END_HIDDEN_DECLS
#endif
--
2.17.1

View file

@ -0,0 +1,193 @@
From c7aacb08e50b0ca1f9c8f027755eecc57828b8e0 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 20 Mar 2020 01:11:59 +0300
Subject: [PATCH 39/87] gost: add support for magma-ctr-acpkm mode
Add support for CTR-ACPKM mode for Magma cipher (see RFC 8645, Section
6.2.2).
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/evp/c_all.c | 1 +
src/lib/libcrypto/evp/e_magma.c | 60 ++++++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 1 +
src/lib/libcrypto/gost/gost.h | 2 +
src/lib/libcrypto/gost/gost2814789.c | 13 +++++
src/regress/lib/libcrypto/evp/evptests.txt | 4 ++
7 files changed, 82 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index d1d317fbd..142cebf46 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1733,6 +1733,7 @@ EVP_kuznyechik_ofb
EVP_magma_cbc
EVP_magma_cfb64
EVP_magma_ctr
+EVP_magma_ctr_acpkm
EVP_magma_ecb
EVP_magma_ofb
EVP_md4
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index 2bb9a9a24..9d66ad40f 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -234,6 +234,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_magma_cfb64());
EVP_add_cipher(EVP_magma_ofb());
EVP_add_cipher(EVP_magma_ctr());
+ EVP_add_cipher(EVP_magma_ctr_acpkm());
EVP_add_cipher(EVP_kuznyechik_ecb());
EVP_add_cipher(EVP_kuznyechik_cbc());
EVP_add_cipher(EVP_kuznyechik_cfb128());
diff --git a/src/lib/libcrypto/evp/e_magma.c b/src/lib/libcrypto/evp/e_magma.c
index c88b25827..0311e04b1 100644
--- a/src/lib/libcrypto/evp/e_magma.c
+++ b/src/lib/libcrypto/evp/e_magma.c
@@ -58,6 +58,24 @@ magma_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
}
}
+static int
+magma_acpkm_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+ EVP_MAGMA_CTX *key = EVP_C_DATA(EVP_MAGMA_CTX, ctx);
+
+ switch (type) {
+ case EVP_CTRL_GOST_SET_MESHING:
+ key->ks.key_meshing = arg;
+ return 1;
+ case EVP_CTRL_INIT:
+ /* deafult for tests */
+ key->ks.key_meshing = 16;
+ return 1;
+ default:
+ return magma_ctl(ctx, type, arg, ptr);
+ }
+}
+
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)
@@ -120,6 +138,39 @@ magma_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *i
return 1;
}
+static int
+magma_ctr_acpkm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+ size_t len)
+{
+ EVP_MAGMA_CTX *key = EVP_C_DATA(EVP_MAGMA_CTX, ctx);
+
+ CRYPTO_ctr64_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_acpkm_encrypt);
+ return 1;
+}
+
+static int
+magma_ctr_acpkm_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* Also set meshing section size here.
+ * There is no other good place to enable meshing for CMS
+ */
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 8 * 1024, 0);
+
+ return gost3412_ctr_acpkm_set_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx));
+}
+
+static int
+magma_ctr_acpkm_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* Also set meshing section size here.
+ * There is no other good place to enable meshing for CMS
+ */
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 8 * 1024, 0);
+
+ return gost3412_ctr_acpkm_get_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx));
+}
+
IMPLEMENT_BLOCK_CIPHER(magma, ks, Magma, EVP_MAGMA_CTX,
NID_magma, 8, 32, 8, 64, 0, magma_init_key, NULL,
EVP_CIPHER_set_asn1_iv,
@@ -133,4 +184,13 @@ BLOCK_CIPHER_def1(magma, ctr, ctr, CTR, EVP_MAGMA_CTX,
EVP_CIPHER_get_asn1_iv,
magma_ctl)
+#define NID_magma_ctr_acpkm NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm
+
+BLOCK_CIPHER_def1(magma, ctr_acpkm, ctr_acpkm, CTR, EVP_MAGMA_CTX,
+ NID_magma, 1, 32, 4, EVP_CIPH_CTRL_INIT | EVP_CIPH_ALWAYS_CALL_INIT,
+ magma_ctr_init_key, NULL,
+ magma_ctr_acpkm_set_asn1_params,
+ magma_ctr_acpkm_get_asn1_params,
+ magma_acpkm_ctl)
+
#endif
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 77b3a4f8e..9e2ed23df 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -853,6 +853,7 @@ const EVP_CIPHER *EVP_magma_cbc(void);
const EVP_CIPHER *EVP_magma_cfb64(void);
const EVP_CIPHER *EVP_magma_ofb(void);
const EVP_CIPHER *EVP_magma_ctr(void);
+const EVP_CIPHER *EVP_magma_ctr_acpkm(void);
const EVP_CIPHER *EVP_kuznyechik_ecb(void);
const EVP_CIPHER *EVP_kuznyechik_cbc(void);
const EVP_CIPHER *EVP_kuznyechik_cfb128(void);
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index 421ca29f3..2bddf038e 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -91,6 +91,8 @@ void Magma_encrypt(const unsigned char *in, unsigned char *out,
const MAGMA_KEY *key);
void Magma_decrypt(const unsigned char *in, unsigned char *out,
const MAGMA_KEY *key);
+void Magma_acpkm_encrypt(const unsigned char *in, unsigned char *out,
+ MAGMA_KEY *key);
#define KUZNYECHIK_KEY_SIZE 32
#define KUZNYECHIK_SUBKEYS_SIZE (16 * 10)
diff --git a/src/lib/libcrypto/gost/gost2814789.c b/src/lib/libcrypto/gost/gost2814789.c
index c9deee695..15449c6b4 100644
--- a/src/lib/libcrypto/gost/gost2814789.c
+++ b/src/lib/libcrypto/gost/gost2814789.c
@@ -205,6 +205,19 @@ Magma_decrypt(const unsigned char *in, unsigned char *out,
be_l2c(n2, out);
}
+void
+Magma_acpkm_encrypt(const unsigned char *in,
+ unsigned char *out,
+ MAGMA_KEY *key)
+{
+ if (key->key_meshing && key->count == key->key_meshing) {
+ acpkm_key_mesh(key, (acpkm_block *)Magma_encrypt, (acpkm_set_key *)Magma_set_key_int, 8, 32);
+ key->count = 0;
+ }
+ Magma_encrypt(in, out, key);
+ key->count += 8;
+}
+
static void
Gost2814789_mac(const unsigned char *in, unsigned char *mac,
GOST2814789_KEY *key)
diff --git a/src/regress/lib/libcrypto/evp/evptests.txt b/src/regress/lib/libcrypto/evp/evptests.txt
index 064da8a12..69d856826 100644
--- a/src/regress/lib/libcrypto/evp/evptests.txt
+++ b/src/regress/lib/libcrypto/evp/evptests.txt
@@ -401,6 +401,10 @@ magma-ofb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:123
magma-cfb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:db37e0e266903c83b571ee29cca54ce791fabcb3abbe2fe3ff5d972d770f6ae9:1
magma-cfb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:db37e0e266903c83b571ee29cca54ce791fabcb3abbe2fe3ff5d972d770f6ae9:0
+# R 1323565.1.017-2018
+magma-ctr-acpkm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:12345678:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899:2ab81deeeb1e4cab68e104c4bd6b94eac72c67af6c2e5b6b0eafb61770f1b32ea1ae71149eed1382abd467180672ec6f84a2f15b3fca72c1:1
+magma-ctr-acpkm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:12345678:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899:2ab81deeeb1e4cab68e104c4bd6b94eac72c67af6c2e5b6b0eafb61770f1b32ea1ae71149eed1382abd467180672ec6f84a2f15b3fca72c1:0
+
# GOST R 34.12-2015
kuznyechik-ecb:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef::1122334455667700ffeeddccbbaa9988:7f679d90bebc24305a468d42b9d4edcd:1
kuznyechik-ecb:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef::1122334455667700ffeeddccbbaa9988:7f679d90bebc24305a468d42b9d4edcd:0
--
2.17.1

View file

@ -0,0 +1,188 @@
From da4b36b194bb2856203ce0987a61a0fe201d625f Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 20 Mar 2020 01:11:59 +0300
Subject: [PATCH 40/87] gost: add support for kuznyechik-ctr-acpkm mode
Add support for CTR-ACPKM mode for Kuznyechik cipher (see RFC 8645,
Section 6.2.2).
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/evp/c_all.c | 1 +
src/lib/libcrypto/evp/e_kuznyechik.c | 60 ++++++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 1 +
src/lib/libcrypto/gost/gost.h | 2 +
src/lib/libcrypto/gost/kuznyechik.c | 13 +++++
src/regress/lib/libcrypto/evp/evptests.txt | 4 ++
7 files changed, 82 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index 142cebf46..c4edd9eb6 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1728,6 +1728,7 @@ EVP_idea_ofb
EVP_kuznyechik_cbc
EVP_kuznyechik_cfb64
EVP_kuznyechik_ctr
+EVP_kuznyechik_ctr_acpkm
EVP_kuznyechik_ecb
EVP_kuznyechik_ofb
EVP_magma_cbc
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index 9d66ad40f..c15be0c4f 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -240,6 +240,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_kuznyechik_cfb128());
EVP_add_cipher(EVP_kuznyechik_ofb());
EVP_add_cipher(EVP_kuznyechik_ctr());
+ EVP_add_cipher(EVP_kuznyechik_ctr_acpkm());
#endif
#ifndef OPENSSL_NO_SM4
diff --git a/src/lib/libcrypto/evp/e_kuznyechik.c b/src/lib/libcrypto/evp/e_kuznyechik.c
index ebb857c62..5fd53aff6 100644
--- a/src/lib/libcrypto/evp/e_kuznyechik.c
+++ b/src/lib/libcrypto/evp/e_kuznyechik.c
@@ -64,6 +64,24 @@ kuznyechik_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
}
}
+static int
+kuznyechik_acpkm_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+ EVP_KUZNYECHIK_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_CTX, ctx);
+
+ switch (type) {
+ case EVP_CTRL_GOST_SET_MESHING:
+ key->ks.key_meshing = arg;
+ return 1;
+ case EVP_CTRL_INIT:
+ /* deafult for tests */
+ key->ks.key_meshing = 32;
+ return 1;
+ default:
+ return kuznyechik_ctl(ctx, type, arg, ptr);
+ }
+}
+
static void
Kuznyechik_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
const KUZNYECHIK_KEY *key, unsigned char *ivec, const int enc)
@@ -126,6 +144,39 @@ kuznyechik_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned ch
return 1;
}
+static int
+kuznyechik_ctr_acpkm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+ size_t len)
+{
+ EVP_KUZNYECHIK_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_CTX, ctx);
+
+ CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block128_f)Kuznyechik_acpkm_encrypt);
+ return 1;
+}
+
+static int
+kuznyechik_ctr_acpkm_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* Also set meshing section size here.
+ * There is no other good place to enable meshing for CMS
+ */
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 256 * 1024, 0);
+
+ return gost3412_ctr_acpkm_set_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx));
+}
+
+static int
+kuznyechik_ctr_acpkm_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* Also set meshing section size here.
+ * There is no other good place to enable meshing for CMS
+ */
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 256 * 1024, 0);
+
+ return gost3412_ctr_acpkm_get_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx));
+}
+
IMPLEMENT_BLOCK_CIPHER(kuznyechik, ks, Kuznyechik, EVP_KUZNYECHIK_CTX,
NID_kuznyechik, 16, 32, 16, 128, 0, kuznyechik_init_key, NULL,
EVP_CIPHER_set_asn1_iv,
@@ -139,4 +190,13 @@ BLOCK_CIPHER_def1(kuznyechik, ctr, ctr, CTR, EVP_KUZNYECHIK_CTX,
EVP_CIPHER_get_asn1_iv,
kuznyechik_ctl)
+#define NID_kuznyechik_ctr_acpkm NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm
+
+BLOCK_CIPHER_def1(kuznyechik, ctr_acpkm, ctr_acpkm, CTR, EVP_KUZNYECHIK_CTX,
+ NID_kuznyechik, 1, 32, 8, EVP_CIPH_CTRL_INIT | EVP_CIPH_ALWAYS_CALL_INIT,
+ kuznyechik_ctr_init_key, NULL,
+ kuznyechik_ctr_acpkm_set_asn1_params,
+ kuznyechik_ctr_acpkm_get_asn1_params,
+ kuznyechik_acpkm_ctl)
+
#endif
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 9e2ed23df..1ef416041 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -859,6 +859,7 @@ const EVP_CIPHER *EVP_kuznyechik_cbc(void);
const EVP_CIPHER *EVP_kuznyechik_cfb128(void);
const EVP_CIPHER *EVP_kuznyechik_ofb(void);
const EVP_CIPHER *EVP_kuznyechik_ctr(void);
+const EVP_CIPHER *EVP_kuznyechik_ctr_acpkm(void);
#endif
#ifndef OPENSSL_NO_SM4
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index 2bddf038e..e84a7625b 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -111,6 +111,8 @@ void Kuznyechik_encrypt(const unsigned char *in, unsigned char *out,
const KUZNYECHIK_KEY *key);
void Kuznyechik_decrypt(const unsigned char *in, unsigned char *out,
const KUZNYECHIK_KEY *key);
+void Kuznyechik_acpkm_encrypt(const unsigned char *in, unsigned char *out,
+ KUZNYECHIK_KEY *key);
typedef struct {
ASN1_OCTET_STRING *iv;
diff --git a/src/lib/libcrypto/gost/kuznyechik.c b/src/lib/libcrypto/gost/kuznyechik.c
index 862b099fd..e2db0933a 100644
--- a/src/lib/libcrypto/gost/kuznyechik.c
+++ b/src/lib/libcrypto/gost/kuznyechik.c
@@ -234,4 +234,17 @@ Kuznyechik_decrypt(const unsigned char *src, unsigned char *dst,
Sinv(dst, temp);
memxor(dst, ctx->key + 16 * 0);
}
+
+void
+Kuznyechik_acpkm_encrypt(const unsigned char *in,
+ unsigned char *out,
+ KUZNYECHIK_KEY *key)
+{
+ if (key->key_meshing && key->count == key->key_meshing) {
+ acpkm_key_mesh(key, (acpkm_block *)Kuznyechik_encrypt, (acpkm_set_key *)Kuznyechik_set_enc_key, 16, 32);
+ key->count = 0;
+ }
+ Kuznyechik_encrypt(in, out, key);
+ key->count += 16;
+}
#endif
diff --git a/src/regress/lib/libcrypto/evp/evptests.txt b/src/regress/lib/libcrypto/evp/evptests.txt
index 69d856826..0c741d5dc 100644
--- a/src/regress/lib/libcrypto/evp/evptests.txt
+++ b/src/regress/lib/libcrypto/evp/evptests.txt
@@ -422,3 +422,7 @@ kuznyechik-ofb128:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcd
kuznyechik-ofb128:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0a1b2c3d4e5f00112:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011:81800a59b1842b24ff1f795e897abd95779146db2d93a94ed93cf68b32397f19e93c9e57441d870545f24036a58ceea3cf3f0061d56423545b960d864cc868da:0
kuznyechik-cfb128:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0a1b2c3d4e5f00112:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011:81800a59b1842b24ff1f795e897abd9568c1b99c4df59cc7951e3739b5b3cdbf073f4dd2d6deb3cfb026545f7af1d8e8e1c852e9a8567162dbb5da7f66dea926:1
kuznyechik-cfb128:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0a1b2c3d4e5f00112:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011:81800a59b1842b24ff1f795e897abd9568c1b99c4df59cc7951e3739b5b3cdbf073f4dd2d6deb3cfb026545f7af1d8e8e1c852e9a8567162dbb5da7f66dea926:0
+
+# R 1323565.1.017-2018
+kuznyechik-ctr-acpkm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a001133445566778899aabbcceeff0a001122445566778899aabbcceeff0a001122335566778899aabbcceeff0a0011223344:f195d8bec10ed1dbd57b5fa240bda1b885eee733f6a13e5df33ce4b33c45dee44bceeb8f646f4c55001706275e85e800587c4df568d094393e4834afd0805046cf30f57686aeece11cfc6c316b8a896edffd07ec813636460c4f3b743423163e6409a9c282fac8d469d221e7fbd6de5d:1
+kuznyechik-ctr-acpkm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a001133445566778899aabbcceeff0a001122445566778899aabbcceeff0a001122335566778899aabbcceeff0a0011223344:f195d8bec10ed1dbd57b5fa240bda1b885eee733f6a13e5df33ce4b33c45dee44bceeb8f646f4c55001706275e85e800587c4df568d094393e4834afd0805046cf30f57686aeece11cfc6c316b8a896edffd07ec813636460c4f3b743423163e6409a9c282fac8d469d221e7fbd6de5d:0
--
2.17.1

View file

@ -0,0 +1,249 @@
From 608d04f4bc23c308b6792b414b8782669379ff09 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sat, 18 Apr 2020 14:17:34 +0300
Subject: [PATCH 41/87] kdftree: add functions implementing KDF_TREE function
Add support for KDF_TREE function from RFC 7836. Unline original RFC
which enforces using of GOST R 34.11 (Streebog-256), these functions are
made generic to use any EVP_MD underneath.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 2 +
src/lib/libcrypto/kdftree/kdftree.c | 156 ++++++++++++++++++++++++++++
src/lib/libcrypto/kdftree/kdftree.h | 47 +++++++++
3 files changed, 205 insertions(+)
create mode 100644 src/lib/libcrypto/kdftree/kdftree.c
create mode 100644 src/lib/libcrypto/kdftree/kdftree.h
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index c4edd9eb6..287c86d2c 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1838,6 +1838,8 @@ HMAC_Update
ISSUING_DIST_POINT_free
ISSUING_DIST_POINT_it
ISSUING_DIST_POINT_new
+KDF_TREE
+KDF_TREE_SIMPLE
LONG_it
MD4
MD4_Final
diff --git a/src/lib/libcrypto/kdftree/kdftree.c b/src/lib/libcrypto/kdftree/kdftree.c
new file mode 100644
index 000000000..4dc7b0096
--- /dev/null
+++ b/src/lib/libcrypto/kdftree/kdftree.c
@@ -0,0 +1,156 @@
+/* $OpenBSD: tlstree.h,v 1.4 2019/11/21 20:02:20 tim 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 <openssl/kdftree.h>
+#include <openssl/hmac.h>
+
+#include <string.h>
+
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+static int
+kdf_tree_block(HMAC_CTX *ctx,
+ const unsigned char *i, unsigned int i_length,
+ const unsigned char *label, unsigned int label_length,
+ const unsigned char *seed, unsigned int seed_length,
+ const unsigned char *l, unsigned int l_length,
+ unsigned char *out, unsigned int *length)
+{
+ /* i label 0x00 seed l */
+ static const unsigned char data[1] = { 0x00 };
+
+ if (!HMAC_Init_ex(ctx, NULL, 0, NULL, NULL) ||
+ !HMAC_Update(ctx, i, i_length) ||
+ !HMAC_Update(ctx, label, label_length) ||
+ !HMAC_Update(ctx, data, 1) ||
+ !HMAC_Update(ctx, seed, seed_length) ||
+ !HMAC_Update(ctx, l, l_length))
+ return 0;
+
+ return HMAC_Final(ctx, out, length);
+}
+
+int KDF_TREE(const EVP_MD *md, ENGINE *impl,
+ const unsigned char *key, unsigned int key_length,
+ const unsigned char *label, unsigned int label_length,
+ const unsigned char *seed, unsigned int seed_length,
+ size_t r,
+ unsigned char *out, unsigned int length)
+{
+ HMAC_CTX ctx;
+ unsigned int i;
+ unsigned char i_block[4], l_block[8];
+ unsigned int l_length, l_off;
+ unsigned char *p;
+ int md_size = EVP_MD_size(md);
+
+ HMAC_CTX_init(&ctx);
+
+ if (!HMAC_Init_ex(&ctx, key, key_length, md, impl))
+ return 0;
+
+ p = l_block;
+ /* bitlength */
+ l2c(length >> 29, p);
+ l2c(length * 8, p);
+
+ /* Calculate how many bytes will it take */
+ for (l_off = 0; l_off < 8; l_off++)
+ if (l_block[l_off] != 0)
+ break;
+
+ l_length = 8 - l_off;
+ for (i = 1; length >= md_size; i++) {
+ unsigned int block = md_size;
+ p = i_block;
+ l2c(i, p);
+ if (!kdf_tree_block(&ctx,
+ i_block + 4 - r, r,
+ label, label_length,
+ seed, seed_length,
+ l_block + l_off, l_length,
+ out, &block)) {
+ HMAC_CTX_cleanup(&ctx);
+ return 0;
+ }
+ out += block;
+ length -= block;
+ }
+ if (length > 0) {
+ unsigned char tmp[EVP_MAX_MD_SIZE];
+ unsigned int block = length;
+
+ p = i_block;
+ l2c(i, p);
+ if (!kdf_tree_block(&ctx,
+ i_block + 4 - r, r,
+ label, label_length,
+ seed, seed_length,
+ l_block + l_off, l_length,
+ tmp, &block)) {
+ HMAC_CTX_cleanup(&ctx);
+ return 0;
+ }
+ memcpy(out, tmp, length);
+ }
+ HMAC_CTX_cleanup(&ctx);
+
+ return 1;
+}
+
+int KDF_TREE_SIMPLE(const EVP_MD *md, ENGINE *impl,
+ const unsigned char *key, unsigned int key_length,
+ const unsigned char *label, unsigned int label_length,
+ const unsigned char *seed, unsigned int seed_length,
+ unsigned char *out)
+{
+ HMAC_CTX ctx;
+ static unsigned char data1[1] = { 0x01 };
+ unsigned char data2[2];
+ int d2_length;
+ int md_size = EVP_MD_size(md);
+ int ret = 1;
+
+ /* bitlength */
+ if (md_size >= 32) {
+ data2[0] = md_size / 32;
+ data2[1] = (md_size * 8) & 0xff;
+ d2_length = 2;
+ } else {
+ data2[0] = (md_size * 8) & 0xff;
+ d2_length = 1;
+ }
+
+ HMAC_CTX_init(&ctx);
+
+ if (!HMAC_Init_ex(&ctx, key, key_length, md, impl) ||
+ !kdf_tree_block(&ctx,
+ data1, 1,
+ label, label_length,
+ seed, seed_length,
+ data2, d2_length,
+ out, &md_size))
+ ret = 0;
+
+ HMAC_CTX_cleanup(&ctx);
+
+ return ret;
+}
diff --git a/src/lib/libcrypto/kdftree/kdftree.h b/src/lib/libcrypto/kdftree/kdftree.h
new file mode 100644
index 000000000..132f70690
--- /dev/null
+++ b/src/lib/libcrypto/kdftree/kdftree.h
@@ -0,0 +1,47 @@
+/* $OpenBSD: kdftree.h,v 1.4 2019/11/21 20:02:20 tim 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.
+ */
+
+#ifndef OPENSSL_HEADER_KDFTREE_H
+#define OPENSSL_HEADER_KDFTREE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include <openssl/evp.h>
+
+/* See RFC 7836 Sections 4.4 */
+int KDF_TREE(const EVP_MD *md, ENGINE *impl,
+ const unsigned char *key, unsigned int key_length,
+ const unsigned char *label, unsigned int label_length,
+ const unsigned char *seed, unsigned int seed_length,
+ size_t r,
+ unsigned char *out, unsigned int length);
+
+/* KDF function from RFC 7836 Section 4.5. Fast equivalent of KDF_TREE with r=1 and L=EVP_MD_size(md) */
+int KDF_TREE_SIMPLE(const EVP_MD *md, ENGINE *impl,
+ const unsigned char *key, unsigned int key_length,
+ const unsigned char *label, unsigned int label_length,
+ const unsigned char *seed, unsigned int seed_length,
+ unsigned char *out);
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_KDFTREE_H */
--
2.17.1

View file

@ -0,0 +1,823 @@
From b7dd5628589230bf30bcd88d4d21cce70adb464b Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 17:04:15 +0300
Subject: [PATCH 42/87] gost: add support for new GOST key transport data
format
Add support for new GOST key transport data format used by CTR-OMAC
ciphersuites.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/gost/gost.h | 5 +
src/lib/libcrypto/gost/gost_asn1.c | 59 ++++
src/lib/libcrypto/gost/gost_asn1.h | 12 +
src/lib/libcrypto/gost/gost_kdf.c | 174 +++++++++++
src/lib/libcrypto/gost/gost_locl.h | 17 ++
src/lib/libcrypto/gost/gostr341001.c | 10 +-
src/lib/libcrypto/gost/gostr341001_pmeth.c | 318 +++++++++++++++++++--
7 files changed, 565 insertions(+), 30 deletions(-)
create mode 100644 src/lib/libcrypto/gost/gost_kdf.c
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index e84a7625b..6a2b60670 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -228,10 +228,15 @@ size_t GOST_KEY_get_size(const GOST_KEY * r);
#define EVP_PKEY_CTRL_GOST_SIG_FORMAT (EVP_PKEY_ALG_CTRL+2)
#define EVP_PKEY_CTRL_GOST_SET_DIGEST (EVP_PKEY_ALG_CTRL+3)
#define EVP_PKEY_CTRL_GOST_GET_DIGEST (EVP_PKEY_ALG_CTRL+4)
+#define EVP_PKEY_CTRL_GOST_ENC_FORMAT (EVP_PKEY_ALG_CTRL+5)
#define GOST_SIG_FORMAT_SR_BE 0
#define GOST_SIG_FORMAT_RS_LE 1
+#define GOST_ENC_FORMAT_4490 0 /* RFC 4490, TLS CNT-IMIT */
+#define GOST_ENC_FORMAT_PSKEY_MAGMA 1 /* CMS, TLS CTR-OMAC, Magma-encoded */
+#define GOST_ENC_FORMAT_PSKEY_KUZNYECHIK 2 /* CMS, TLS CTR-OMAC, Kuznyechik-encoded */
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
diff --git a/src/lib/libcrypto/gost/gost_asn1.c b/src/lib/libcrypto/gost/gost_asn1.c
index 14e46afab..f56486d2a 100644
--- a/src/lib/libcrypto/gost/gost_asn1.c
+++ b/src/lib/libcrypto/gost/gost_asn1.c
@@ -474,4 +474,63 @@ gost3412_ctr_acpkm_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params, unsig
return 1;
}
+static const ASN1_TEMPLATE GOST_KEY_TRANSPORT_PSKEY_seq_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(GOST_KEY_TRANSPORT_PSKEY, key_exp),
+ .field_name = "key_exp",
+ .item = &ASN1_OCTET_STRING_it,
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(GOST_KEY_TRANSPORT_PSKEY, ephem_key),
+ .field_name = "ephem_key",
+ .item = &X509_PUBKEY_it,
+ },
+ {
+ .flags = ASN1_TFLG_OPTIONAL,
+ .tag = 0,
+ .offset = offsetof(GOST_KEY_TRANSPORT_PSKEY, ukm),
+ .field_name = "ukm",
+ .item = &ASN1_OCTET_STRING_it,
+ },
+};
+
+const ASN1_ITEM GOST_KEY_TRANSPORT_PSKEY_it = {
+ .itype = ASN1_ITYPE_NDEF_SEQUENCE,
+ .utype = V_ASN1_SEQUENCE,
+ .templates = GOST_KEY_TRANSPORT_PSKEY_seq_tt,
+ .tcount = sizeof(GOST_KEY_TRANSPORT_PSKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
+ .funcs = NULL,
+ .size = sizeof(GOST_KEY_TRANSPORT_PSKEY),
+ .sname = "GOST_KEY_TRANSPORT_PSKEY",
+};
+
+GOST_KEY_TRANSPORT_PSKEY *
+d2i_GOST_KEY_TRANSPORT_PSKEY(GOST_KEY_TRANSPORT_PSKEY **a, const unsigned char **in, long len)
+{
+ return (GOST_KEY_TRANSPORT_PSKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+ &GOST_KEY_TRANSPORT_PSKEY_it);
+}
+
+int
+i2d_GOST_KEY_TRANSPORT_PSKEY(GOST_KEY_TRANSPORT_PSKEY *a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_TRANSPORT_PSKEY_it);
+}
+
+GOST_KEY_TRANSPORT_PSKEY *
+GOST_KEY_TRANSPORT_PSKEY_new(void)
+{
+ return (GOST_KEY_TRANSPORT_PSKEY *)ASN1_item_new(&GOST_KEY_TRANSPORT_PSKEY_it);
+}
+
+void
+GOST_KEY_TRANSPORT_PSKEY_free(GOST_KEY_TRANSPORT_PSKEY *a)
+{
+ ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_TRANSPORT_PSKEY_it);
+}
+
#endif
diff --git a/src/lib/libcrypto/gost/gost_asn1.h b/src/lib/libcrypto/gost/gost_asn1.h
index 5af16e00e..1ae5e6706 100644
--- a/src/lib/libcrypto/gost/gost_asn1.h
+++ b/src/lib/libcrypto/gost/gost_asn1.h
@@ -123,6 +123,18 @@ GOST3412_ENCRYPTION_PARAMS *d2i_GOST3412_ENCRYPTION_PARAMS(GOST3412_ENCRYPTION_P
int i2d_GOST3412_ENCRYPTION_PARAMS(GOST3412_ENCRYPTION_PARAMS *a, unsigned char **out);
extern const ASN1_ITEM GOST3412_ENCRYPTION_PARAMS_it;
+typedef struct {
+ ASN1_OCTET_STRING *key_exp;
+ X509_PUBKEY *ephem_key;
+ ASN1_OCTET_STRING *ukm;
+} GOST_KEY_TRANSPORT_PSKEY;
+
+GOST_KEY_TRANSPORT_PSKEY *GOST_KEY_TRANSPORT_PSKEY_new(void);
+void GOST_KEY_TRANSPORT_PSKEY_free(GOST_KEY_TRANSPORT_PSKEY *a);
+GOST_KEY_TRANSPORT_PSKEY *d2i_GOST_KEY_TRANSPORT_PSKEY(GOST_KEY_TRANSPORT_PSKEY **a, const unsigned char **in, long len);
+int i2d_GOST_KEY_TRANSPORT_PSKEY(GOST_KEY_TRANSPORT_PSKEY *a, unsigned char **out);
+extern const ASN1_ITEM GOST_KEY_TRANSPORT_PSKEY_it;
+
__END_HIDDEN_DECLS
#endif
diff --git a/src/lib/libcrypto/gost/gost_kdf.c b/src/lib/libcrypto/gost/gost_kdf.c
new file mode 100644
index 000000000..be497aea0
--- /dev/null
+++ b/src/lib/libcrypto/gost/gost_kdf.c
@@ -0,0 +1,174 @@
+/* $OpenBSD: gost_kdf.c,v 1.4 2017/01/29 17:49:23 beck Exp $ */
+/*
+ * Copyright (c) 2020 Dmitry Baryshkov <dbaryshkov@gmail.com>
+ *
+ * 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 <string.h>
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_GOST
+#include <openssl/gost.h>
+#include <openssl/err.h>
+#include <openssl/kdftree.h>
+#include <openssl/hmac.h>
+#include <openssl/cmac.h>
+
+#include "gost_locl.h"
+
+int
+gost_kexp15(const EVP_CIPHER *ctr_cipher, const EVP_CIPHER *cmac_cipher,
+ const unsigned char *key, unsigned int key_length,
+ const unsigned char *key_mac,
+ const unsigned char *key_enc,
+ const unsigned char *iv,
+ unsigned char *out, size_t *out_length)
+{
+
+ CMAC_CTX *cmac_ctx = CMAC_CTX_new();
+ EVP_CIPHER_CTX ctx;
+ unsigned char cmac[EVP_MAX_BLOCK_LENGTH];
+ size_t cmac_length = sizeof(cmac);
+ unsigned int len = *out_length;
+ unsigned int tmp;
+
+ if (CMAC_Init(cmac_ctx, key_mac, EVP_CIPHER_key_length(cmac_cipher), cmac_cipher, NULL) <= 0 ||
+ CMAC_Update(cmac_ctx, iv, ctr_cipher->iv_len) <= 0 ||
+ CMAC_Update(cmac_ctx, key, key_length) <= 0 ||
+ CMAC_Final(cmac_ctx, cmac, &cmac_length) <= 0) {
+ CMAC_CTX_free(cmac_ctx);
+ return 0;
+ }
+
+ CMAC_CTX_free(cmac_ctx);
+
+ EVP_CIPHER_CTX_init(&ctx);
+ if (!EVP_EncryptInit_ex(&ctx, ctr_cipher, NULL, key_enc, iv) ||
+ !EVP_CIPHER_CTX_set_padding(&ctx, 0) ||
+ !EVP_EncryptUpdate(&ctx, out, &len, key, key_length)) {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return 0;
+ }
+
+ tmp = *out_length - len;
+ if (!EVP_EncryptUpdate(&ctx, out + len, &tmp, cmac, cmac_length)) {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return 0;
+ }
+
+ len += tmp;
+ tmp = *out_length - len;
+ if (!EVP_EncryptFinal_ex(&ctx, out + len, &tmp)) {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return 0;
+ }
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ len += tmp;
+ *out_length = len;
+
+ return 1;
+}
+
+int
+gost_kimp15(const EVP_CIPHER *ctr_cipher, const EVP_CIPHER *cmac_cipher,
+ const unsigned char *sexp, unsigned int sexp_length,
+ const unsigned char *key_mac,
+ const unsigned char *key_enc,
+ const unsigned char *iv,
+ unsigned char *out, size_t *out_length)
+{
+ CMAC_CTX *cmac_ctx = CMAC_CTX_new();
+ EVP_CIPHER_CTX ctx;
+ unsigned char cmac[EVP_MAX_BLOCK_LENGTH];
+ size_t cmac_length;
+ unsigned char tmp[EVP_MAX_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH];
+ unsigned int len = sizeof(tmp);
+ unsigned int len2;
+
+ cmac_length = EVP_CIPHER_block_size(cmac_cipher);
+ if (*out_length > EVP_MAX_KEY_LENGTH || sexp_length < cmac_length || sexp_length != 32 + cmac_length) {
+ EVPerror(EVP_R_BAD_BLOCK_LENGTH);
+ return 0;
+ }
+
+ EVP_CIPHER_CTX_init(&ctx);
+ if (!EVP_DecryptInit_ex(&ctx, ctr_cipher, NULL, key_enc, iv) ||
+ !EVP_CIPHER_CTX_set_padding(&ctx, 0) ||
+ !EVP_DecryptUpdate(&ctx, tmp, &len, sexp, sexp_length)) {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ return 0;
+ }
+
+ len2 = sizeof(tmp) - len;
+ if (!EVP_DecryptFinal_ex(&ctx, tmp + len, &len2)) {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ return 0;
+ }
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ len += len2;
+
+ len2 = sexp_length - cmac_length;
+ if (CMAC_Init(cmac_ctx, key_mac, EVP_CIPHER_key_length(cmac_cipher), cmac_cipher, NULL) <= 0 ||
+ CMAC_Update(cmac_ctx, iv, ctr_cipher->iv_len) <= 0 ||
+ CMAC_Update(cmac_ctx, tmp, sexp_length - cmac_length) <= 0 ||
+ CMAC_Final(cmac_ctx, cmac, &cmac_length) <= 0) {
+ CMAC_CTX_free(cmac_ctx);
+ GOSTerror(GOST_R_SIGNATURE_MISMATCH);
+ return 0;
+ }
+
+ CMAC_CTX_free(cmac_ctx);
+
+ if (timingsafe_memcmp(cmac, tmp + len2, cmac_length)) {
+ GOSTerror(GOST_R_SIGNATURE_MISMATCH);
+ return 0;
+ }
+
+ memcpy(out, tmp, len2);
+
+ return 1;
+}
+
+int
+gost_keg(EVP_PKEY *pub, EVP_PKEY *priv, int nid,
+ const unsigned char *ukm, unsigned char *keg_out)
+{
+ if (nid == NID_id_tc26_gost3411_2012_512) {
+ if (gost01_VKO_key(pub, priv, ukm, 16, 1, NID_id_tc26_gost3411_2012_512, keg_out) == 0) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ return 0;
+ }
+
+ return 1;
+ } else {
+ unsigned char tmp[32];
+
+ if (gost01_VKO_key(pub, priv, ukm, 16, 1, NID_id_tc26_gost3411_2012_256, tmp) == 0) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ return 0;
+ }
+
+ return KDF_TREE(EVP_streebog256(), NULL,
+ tmp, 32,
+ "kdf tree", 8,
+ ukm + 16, 8,
+ 1,
+ keg_out, 64);
+ }
+}
+#endif
diff --git a/src/lib/libcrypto/gost/gost_locl.h b/src/lib/libcrypto/gost/gost_locl.h
index f512029e1..13e9fd459 100644
--- a/src/lib/libcrypto/gost/gost_locl.h
+++ b/src/lib/libcrypto/gost/gost_locl.h
@@ -121,6 +121,8 @@ extern int VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey,
GOST_KEY *priv_key, const BIGNUM *ukm);
extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn);
extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len);
+extern int gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm,
+ unsigned int ukm_len, int ukm_be, int out_nid, unsigned char *key);
/* GOST R 34.10 parameters */
extern int GostR3410_get_md_digest(int nid);
@@ -128,6 +130,21 @@ extern int GostR3410_get_pk_digest(int nid);
extern int GostR3410_256_param_id(const char *value);
extern int GostR3410_512_param_id(const char *value);
+int gost_keg(EVP_PKEY *pub, EVP_PKEY *priv, int nid,
+ const unsigned char *ukm, unsigned char *keg_out);
+int gost_kexp15(const EVP_CIPHER *cmac_cipher, const EVP_CIPHER *ctr_cipher,
+ const unsigned char *key, unsigned int key_length,
+ const unsigned char *key_mac,
+ const unsigned char *key_enc,
+ const unsigned char *iv,
+ unsigned char *out, size_t *out_length);
+int gost_kimp15(const EVP_CIPHER *cmac_cipher, const EVP_CIPHER *ctr_cipher,
+ const unsigned char *sexp, unsigned int sexp_length,
+ const unsigned char *key_mac,
+ const unsigned char *key_enc,
+ const unsigned char *iv,
+ unsigned char *out, size_t *out_length);
+
__END_HIDDEN_DECLS
#endif
diff --git a/src/lib/libcrypto/gost/gostr341001.c b/src/lib/libcrypto/gost/gostr341001.c
index ba70d5f1f..5ac36d25f 100644
--- a/src/lib/libcrypto/gost/gostr341001.c
+++ b/src/lib/libcrypto/gost/gostr341001.c
@@ -329,7 +329,7 @@ int
VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key,
const BIGNUM *ukm)
{
- BIGNUM *p = NULL, *order = NULL;
+ BIGNUM *p = NULL, *order = NULL, *cofactor = NULL;
const BIGNUM *key = GOST_KEY_get0_private_key(priv_key);
const EC_GROUP *group = GOST_KEY_get0_group(priv_key);
const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey);
@@ -350,7 +350,13 @@ VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key,
goto err;
if (EC_GROUP_get_order(group, order, ctx) == 0)
goto err;
- if (BN_mod_mul(p, key, ukm, order, ctx) == 0)
+ if ((cofactor = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if (EC_GROUP_get_cofactor(group, cofactor, ctx) == 0)
+ goto err;
+ if (BN_mod_mul(p, key, cofactor, order, ctx) == 0)
+ goto err;
+ if (!BN_is_zero(ukm) && BN_mod_mul(p, p, ukm, order, ctx) == 0)
goto err;
if (EC_POINT_mul(group, pnt, NULL, pub_key, p, ctx) == 0)
goto err;
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c
index 0e0cae99e..455337232 100644
--- a/src/lib/libcrypto/gost/gostr341001_pmeth.c
+++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c
@@ -130,8 +130,10 @@ struct gost_pmeth_data {
int digest_nid;
EVP_MD *md;
unsigned char *shared_ukm;
+ unsigned int shared_ukm_len;
int peer_key_used;
int sig_format;
+ int enc_format;
};
static int
@@ -165,8 +167,8 @@ pkey_gost01_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
src_data = EVP_PKEY_CTX_get_data(src);
dst_data = EVP_PKEY_CTX_get_data(dst);
*dst_data = *src_data;
- if (src_data->shared_ukm != NULL)
- dst_data->shared_ukm = NULL;
+ dst_data->shared_ukm = NULL;
+ dst_data->shared_ukm_len = 0;
return 1;
}
@@ -310,11 +312,12 @@ err:
return ok;
}
-static int
+int
gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm,
- unsigned char *key)
+ unsigned int ukm_len, int ukm_be, int out_nid, unsigned char *key)
{
unsigned char hashbuf[128];
+ size_t hash_len;
int digest_nid;
int ret = 0;
BN_CTX *ctx = BN_CTX_new();
@@ -331,7 +334,10 @@ gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm,
if ((Y = BN_CTX_get(ctx)) == NULL)
goto err;
- GOST_le2bn(ukm, 8, UKM);
+ if (ukm_be)
+ BN_bin2bn (ukm, ukm_len, UKM);
+ else
+ GOST_le2bn(ukm, ukm_len, UKM);
digest_nid = GOST_KEY_get_digest(priv_key->pkey.gost);
if (VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost,
@@ -340,27 +346,37 @@ gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm,
switch (digest_nid) {
case NID_id_GostR3411_94_CryptoProParamSet:
- GOST_bn2le(X, hashbuf, 32);
- GOST_bn2le(Y, hashbuf + 32, 32);
- GOSTR341194(hashbuf, 64, key, digest_nid);
- ret = 1;
- break;
case NID_id_tc26_gost3411_2012_256:
GOST_bn2le(X, hashbuf, 32);
GOST_bn2le(Y, hashbuf + 32, 32);
- STREEBOG256(hashbuf, 64, key);
- ret = 1;
+ hash_len = 64;
break;
case NID_id_tc26_gost3411_2012_512:
GOST_bn2le(X, hashbuf, 64);
GOST_bn2le(Y, hashbuf + 64, 64);
- STREEBOG256(hashbuf, 128, key);
- ret = 1;
+ hash_len = 128;
break;
default:
ret = -2;
+ goto err;
+ }
+
+ switch (out_nid) {
+ case NID_id_GostR3411_94_CryptoProParamSet:
+ GOSTR341194(hashbuf, hash_len, key, out_nid);
+ break;
+ case NID_id_tc26_gost3411_2012_256:
+ STREEBOG256(hashbuf, hash_len, key);
+ break;
+ case NID_id_tc26_gost3411_2012_512:
+ STREEBOG512(hashbuf, hash_len, key);
break;
+ default:
+ ret = -2;
+ goto err;
}
+
+ ret = 1;
err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
@@ -368,7 +384,7 @@ err:
}
int
-pkey_gost01_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len,
+pkey_gost01_decrypt_4490(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len,
const unsigned char *in, size_t in_len)
{
const unsigned char *p = in;
@@ -428,8 +444,15 @@ pkey_gost01_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len,
goto err;
}
memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4);
- if (gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey) <= 0)
+ if (gost01_VKO_key(peerkey, priv, wrappedKey, 8, 0,
+ GOST_KEY_get_digest(priv->pkey.gost) ==
+ NID_id_GostR3411_94_CryptoProParamSet ?
+ NID_id_GostR3411_94_CryptoProParamSet :
+ NID_id_tc26_gost3411_2012_256,
+ sharedKey) <= 0) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
goto err;
+ }
if (gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key) == 0) {
GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
goto err;
@@ -464,15 +487,22 @@ pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
return 32;
}
- if (gost01_VKO_key(peer_key, my_key, data->shared_ukm, key) <= 0)
+ if (gost01_VKO_key(peer_key, my_key, data->shared_ukm, 8, 0,
+ GOST_KEY_get_digest(my_key->pkey.gost) ==
+ NID_id_GostR3411_94_CryptoProParamSet ?
+ NID_id_GostR3411_94_CryptoProParamSet :
+ NID_id_tc26_gost3411_2012_256,
+ key) <= 0) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
return 0;
+ }
*keylen = 32;
return 1;
}
int
-pkey_gost01_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len,
+pkey_gost01_encrypt_4490(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len,
const unsigned char *key, size_t key_len)
{
GOST_KEY_TRANSPORT *gkt = NULL;
@@ -484,7 +514,7 @@ pkey_gost01_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len,
EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx);
int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
- if (data->shared_ukm != NULL) {
+ if (data->shared_ukm != NULL && data->shared_ukm_len >= 8) {
memcpy(ukm, data->shared_ukm, 8);
} else /* if (out != NULL) */ {
arc4random_buf(ukm, 8);
@@ -521,22 +551,29 @@ pkey_gost01_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len,
}
if (out != NULL) {
- if (gost01_VKO_key(pubk, sec_key, ukm, shared_key) <= 0)
+ if (gost01_VKO_key(pubk, sec_key, ukm, 8, 0,
+ GOST_KEY_get_digest(pubk->pkey.gost) ==
+ NID_id_GostR3411_94_CryptoProParamSet ?
+ NID_id_GostR3411_94_CryptoProParamSet :
+ NID_id_tc26_gost3411_2012_256,
+ shared_key) <= 0) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
goto err;
+ }
gost_key_wrap_crypto_pro(nid, shared_key, ukm, key,
crypted_key);
}
gkt = GOST_KEY_TRANSPORT_new();
- if (gkt == NULL)
- goto err;
- if (ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8) == 0)
- goto err;
- if (ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40,
- 4) == 0)
+ if (gkt == NULL) {
+ GOSTerror(ERR_R_MALLOC_FAILURE);
goto err;
- if (ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8,
- 32) == 0)
+ }
+ if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8) ||
+ !ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4) ||
+ !ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8, 32)) {
+ GOSTerror(ERR_R_ASN1_LIB);
goto err;
+ }
if (key_is_ephemeral) {
if (X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,
out != NULL ? sec_key : pubk) == 0) {
@@ -568,6 +605,213 @@ err:
return -1;
}
+int
+pkey_gost01_decrypt_pskey(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len,
+ const unsigned char *in, size_t in_len,
+ const EVP_CIPHER *enc_cipher, const EVP_CIPHER *mac_cipher)
+{
+ const unsigned char *p = in;
+ EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
+ GOST_KEY_TRANSPORT_PSKEY *gkt = NULL;
+ struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
+ EVP_PKEY *eph_key = NULL, *peerkey = NULL;
+ unsigned char keg_out[64];
+ const unsigned char *ukm;
+
+ if (key == NULL) {
+ *key_len = 32;
+ return 1;
+ }
+
+ gkt = d2i_GOST_KEY_TRANSPORT_PSKEY(NULL, (const unsigned char **)&p, in_len);
+ if (gkt == NULL) {
+ GOSTerror(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
+ return -1;
+ }
+
+ if (data->shared_ukm_len == 0) {
+ if (!gkt->ukm || gkt->ukm->length != 32) {
+ GOSTerror(ERR_R_ASN1_LIB);
+ goto err;
+ }
+ ukm = gkt->ukm->data;
+ } else if (data->shared_ukm_len != 32) {
+ GOSTerror(GOST_R_INVALID_IV_LENGTH);
+ goto err;
+ } else {
+ ukm = data->shared_ukm;
+ }
+
+ eph_key = X509_PUBKEY_get(gkt->ephem_key);
+ if (eph_key == NULL) {
+ GOSTerror(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
+ goto err;
+ }
+
+ if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) {
+ GOSTerror(GOST_R_INCOMPATIBLE_PEER_KEY);
+ goto err;
+ }
+
+ peerkey = EVP_PKEY_CTX_get0_peerkey(pctx);
+ if (peerkey == NULL) {
+ GOSTerror(GOST_R_NO_PEER_KEY);
+ goto err;
+ }
+
+ /* KEG */
+ if (!gost_keg(peerkey, priv, data->digest_nid, ukm, keg_out)) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ goto err;
+ }
+
+ if (!gost_kimp15(enc_cipher, mac_cipher,
+ gkt->key_exp->data, gkt->key_exp->length,
+ keg_out, keg_out + 32,
+ ukm + 24,
+ key, key_len)) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ goto err;
+ }
+
+ GOST_KEY_TRANSPORT_PSKEY_free(gkt);
+ return 1;
+
+err:
+ GOST_KEY_TRANSPORT_PSKEY_free(gkt);
+ return 0;
+}
+
+int
+pkey_gost01_encrypt_pskey(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len,
+ const unsigned char *key, size_t key_len,
+ const EVP_CIPHER *enc_cipher, const EVP_CIPHER *mac_cipher)
+{
+ GOST_KEY_TRANSPORT_PSKEY *gkt = NULL;
+ struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
+ EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
+ EVP_PKEY *sec_key = NULL;
+ GOST_KEY *tmp_key;
+ unsigned char ukm[32];
+ unsigned char keg_out[64];
+ unsigned char kexp_out[64];
+ size_t kexp_len = sizeof(kexp_out);
+ int tmp_len;
+
+ if (data->shared_ukm == NULL) {
+ arc4random_buf(ukm, sizeof(ukm));
+ } else if (data->shared_ukm_len != sizeof(ukm)) {
+ GOSTerror(GOST_R_INVALID_IV_LENGTH);
+ return 0;
+ } else {
+ memcpy(ukm, data->shared_ukm, sizeof(ukm));
+ }
+
+ if (out) {
+ sec_key = EVP_PKEY_new();
+ if (sec_key == NULL) {
+ GOSTerror(ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ tmp_key = GOST_KEY_new();
+ if (tmp_key == NULL) {
+ GOSTerror(ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), tmp_key) == 0) {
+ GOST_KEY_free(tmp_key);
+ goto err;
+ }
+ if (EVP_PKEY_copy_parameters(sec_key, pubk) == 0)
+ goto err;
+ if (gost2001_keygen(sec_key->pkey.gost) == 0)
+ goto err;
+
+ /* KEG */
+ if (!gost_keg(pubk, sec_key, data->digest_nid, ukm, keg_out)) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ goto err;
+ }
+
+ if (!gost_kexp15(enc_cipher, mac_cipher,
+ key, key_len,
+ keg_out, keg_out + 32,
+ ukm + 24,
+ kexp_out, &kexp_len))
+ goto err;
+ } else {
+ kexp_len = key_len + EVP_CIPHER_block_size(mac_cipher);
+ }
+
+ gkt = GOST_KEY_TRANSPORT_PSKEY_new();
+ if (gkt == NULL)
+ goto err;
+
+ if (!ASN1_OCTET_STRING_set(gkt->key_exp, kexp_out, kexp_len) ||
+ !X509_PUBKEY_set(&gkt->ephem_key, out ? sec_key : pubk))
+ goto err;
+
+ if (data->shared_ukm == NULL &&
+ (((gkt->ukm = ASN1_OCTET_STRING_new()) == NULL) ||
+ !ASN1_OCTET_STRING_set(gkt->ukm, ukm, sizeof(ukm))))
+ goto err;
+
+ tmp_len = i2d_GOST_KEY_TRANSPORT_PSKEY(gkt, NULL);
+ if (!out) {
+ *out_len = tmp_len;
+ } else {
+ if (*out_len < tmp_len)
+ goto err;
+ *out_len = i2d_GOST_KEY_TRANSPORT_PSKEY(gkt, &out);
+ }
+
+ EVP_PKEY_free(sec_key);
+ GOST_KEY_TRANSPORT_PSKEY_free(gkt);
+
+ return 1;
+err:
+ EVP_PKEY_free(sec_key);
+ GOST_KEY_TRANSPORT_PSKEY_free(gkt);
+ return 0;
+}
+
+int
+pkey_gost01_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *out_len,
+ const unsigned char *key, size_t key_len)
+{
+ struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx);
+
+ switch (pctx->enc_format) {
+ case GOST_ENC_FORMAT_4490:
+ return pkey_gost01_decrypt_4490(ctx, out, out_len, key, key_len);
+ case GOST_ENC_FORMAT_PSKEY_MAGMA:
+ return pkey_gost01_decrypt_pskey(ctx, out, out_len, key, key_len, EVP_magma_ctr(), EVP_magma_cbc());
+ case GOST_ENC_FORMAT_PSKEY_KUZNYECHIK:
+ return pkey_gost01_decrypt_pskey(ctx, out, out_len, key, key_len, EVP_kuznyechik_ctr(), EVP_kuznyechik_cbc());
+ default:
+ return -1;
+ }
+}
+
+int
+pkey_gost01_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *out_len,
+ const unsigned char *key, size_t key_len)
+{
+ struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx);
+
+ switch (pctx->enc_format) {
+ case GOST_ENC_FORMAT_4490:
+ return pkey_gost01_encrypt_4490(ctx, out, out_len, key, key_len);
+ case GOST_ENC_FORMAT_PSKEY_MAGMA:
+ return pkey_gost01_encrypt_pskey(ctx, out, out_len, key, key_len, EVP_magma_ctr(), EVP_magma_cbc());
+ case GOST_ENC_FORMAT_PSKEY_KUZNYECHIK:
+ return pkey_gost01_encrypt_pskey(ctx, out, out_len, key, key_len, EVP_kuznyechik_ctr(), EVP_kuznyechik_cbc());
+ default:
+ return -1;
+ }
+}
static int
pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
@@ -604,6 +848,7 @@ pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
memcpy(ukm, p2, p1);
free(pctx->shared_ukm);
pctx->shared_ukm = ukm;
+ pctx->shared_ukm_len = p1;
return 1;
}
@@ -631,6 +876,23 @@ pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_GOST_GET_DIGEST:
*(int *)p2 = pctx->digest_nid;
return 1;
+ case EVP_PKEY_CTRL_GOST_ENC_FORMAT:
+ switch (p1) {
+ case GOST_ENC_FORMAT_4490:
+ /* All keys are supported */
+ break;
+ case GOST_ENC_FORMAT_PSKEY_MAGMA:
+ case GOST_ENC_FORMAT_PSKEY_KUZNYECHIK:
+ if (pctx->digest_nid != NID_id_tc26_gost3411_2012_256 &&
+ pctx->digest_nid != NID_id_tc26_gost3411_2012_512)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ pctx->enc_format = p1;
+ return 1;
+ break;
default:
return -2;
}
--
2.17.1

View file

@ -0,0 +1,380 @@
From cecf218cb638ba4776bce1f702e9ffe2c2e2db12 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 21:54:20 +0300
Subject: [PATCH 43/87] modes: add support for 128-bit MGM mode
Add support for 128-bit MGM (Multilinear Galois Mode) defined in
draft-smyshlyaev-mgm.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/modes/mgm128.c | 308 ++++++++++++++++++++++++++++
src/lib/libcrypto/modes/modes.h | 16 ++
src/lib/libcrypto/modes/modes_lcl.h | 11 +
3 files changed, 335 insertions(+)
create mode 100644 src/lib/libcrypto/modes/mgm128.c
diff --git a/src/lib/libcrypto/modes/mgm128.c b/src/lib/libcrypto/modes/mgm128.c
new file mode 100644
index 000000000..dbd18b0a8
--- /dev/null
+++ b/src/lib/libcrypto/modes/mgm128.c
@@ -0,0 +1,308 @@
+/* $OpenBSD: mgm128.c,v 1.22 2018/01/24 23:03:37 kettenis Exp $ */
+/*
+ * Copyright (c) 2020 Dmitry Baryshkov <dbaryshkov@gmail.com>
+ *
+ * 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 <string.h>
+#include <machine/endian.h>
+
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+
+#define MGM128_BLOCK_SIZE 16
+#define MGM128_POLYNOMIAL U64(0x87)
+
+static void
+mgm128_gf_shift (u64 r[2], const u64 x[2])
+{
+ long mask;
+
+ /* Shift uses big-endian representation. */
+#if BYTE_ORDER != LITTLE_ENDIAN
+ mask = - ((x[0] >> 63) & 1);
+ r[0] = (x[0] << 1) | (x[1] >> 63);
+ r[1] = (x[1] << 1) ^ (mask & (MGM128_POLYNOMIAL));
+#else /* ! WORDS_BIGENDIAN */
+#define RSHIFT_WORD(x) \
+ ((((x) & UINT64_C(0x7f7f7f7f7f7f7f7f)) << 1) \
+ | (((x) & UINT64_C(0x8080808080808000)) >> 15))
+ mask = - ((x[0] >> 7) & 1);
+ r[0] = RSHIFT_WORD(x[0]) | ((x[1] & 0x80) << 49);
+ r[1] = RSHIFT_WORD(x[1]) ^ (mask & (MGM128_POLYNOMIAL << 56));
+# undef RSHIFT_WORD
+#endif /* ! WORDS_BIGENDIAN */
+}
+
+static void
+mgm128_gf_mul_sum(MGM128_CONTEXT *ctx, u64 *x, const uint8_t *y)
+{
+ u64 V[2], Z[2];
+ unsigned i;
+
+ memcpy(V, x, sizeof(V));
+ memset(Z, 0, sizeof(Z));
+
+ for (i = 0; i < MGM128_BLOCK_SIZE; i++)
+ {
+ uint8_t b = y[MGM128_BLOCK_SIZE - i - 1];
+ unsigned j;
+ for (j = 0; j < 8; j++, b >>= 1)
+ {
+ if (b & 1) {
+ Z[0] ^= V[0];
+ Z[1] ^= V[1];
+ }
+
+ mgm128_gf_shift(V, V);
+ }
+ }
+
+ ctx->sum[0] ^= Z[0];
+ ctx->sum[1] ^= Z[1];
+}
+
+static inline void mgm128_inc(unsigned char *counter, u32 n)
+{
+ u8 c;
+
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c) return;
+ } while (n);
+}
+
+void mgm128_hash_block(MGM128_CONTEXT *ctx, const u8 *data)
+{
+ union {u64 u[2]; u8 c[MGM128_BLOCK_SIZE]; } tmp;
+
+ (*ctx->block)(ctx->z, tmp.c, ctx->key);
+ mgm128_gf_mul_sum(ctx, tmp.u, data);
+ mgm128_inc(ctx->z, MGM128_BLOCK_SIZE / 2);
+}
+
+void CRYPTO_mgm128_init(MGM128_CONTEXT *ctx, void *key, block128_f block)
+{
+ memset(ctx,0,sizeof(*ctx));
+ ctx->block = block;
+ ctx->key = key;
+}
+
+void CRYPTO_mgm128_setiv(MGM128_CONTEXT *ctx, const unsigned char *iv)
+{
+ memcpy(ctx->y, iv, MGM128_NONCE_LEN);
+ memcpy(ctx->z, iv, MGM128_NONCE_LEN);
+
+ ctx->y[0] &= 0x7f;
+ ctx->z[0] |= 0x80;
+
+ (*ctx->block)(ctx->y, ctx->y, ctx->key);
+ (*ctx->block)(ctx->z, ctx->z, ctx->key);
+
+ memset(ctx->sum, 0, MGM128_BLOCK_SIZE);
+ memset(ctx->len, 0, MGM128_BLOCK_SIZE);
+}
+
+int CRYPTO_mgm128_aad(MGM128_CONTEXT *ctx, const unsigned char *aad,
+ size_t len)
+{
+ unsigned int n;
+
+ if (ctx->len[1])
+ return -2;
+
+ ctx->len[0] += len * 8;
+
+ n = ctx->a_remain;
+ if (n) {
+ while (n && len) {
+ ctx->part[n] = *(aad++);
+ --len;
+ n = (n + 1) % MGM128_BLOCK_SIZE;
+ }
+ if (n == 0) {
+ mgm128_hash_block(ctx, ctx->part);
+ } else {
+ ctx->a_remain = n;
+ return 0;
+ }
+ }
+
+ while (len >= MGM128_BLOCK_SIZE) {
+ mgm128_hash_block(ctx, aad);
+ aad += MGM128_BLOCK_SIZE;
+ len -= MGM128_BLOCK_SIZE;
+ }
+
+ if (len)
+ memcpy(ctx->part, aad, len);
+
+ ctx->a_remain = len;
+ return 0;
+}
+
+int CRYPTO_mgm128_encrypt(MGM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len)
+{
+ unsigned int n;
+
+ /* Handle AAD remainder */
+ if (ctx->a_remain) {
+ memset(ctx->part + ctx->a_remain, 0, MGM128_BLOCK_SIZE - ctx->a_remain);
+ mgm128_hash_block(ctx, ctx->part);
+ ctx->a_remain = 0;
+ }
+
+ ctx->len[1] += len * 8;
+
+ n = ctx->d_remain;
+ if (n) {
+ while (n && len) {
+ ctx->part[n] ^= *(in++);
+ *(out++) = ctx->part[n];
+ --len;
+ n = (n + 1) % MGM128_BLOCK_SIZE;
+ }
+ if (n == 0) {
+ mgm128_hash_block(ctx, ctx->part);
+ } else {
+ ctx->d_remain = n;
+ return 0;
+ }
+ }
+
+ while (len >= MGM128_BLOCK_SIZE) {
+ (*ctx->block)(ctx->y, ctx->part, ctx->key);
+ mgm128_inc(ctx->y + MGM128_BLOCK_SIZE / 2, MGM128_BLOCK_SIZE / 2);
+ for (n = 0; n < MGM128_BLOCK_SIZE; n++) {
+ out[n] = ctx->part[n] ^ in[n];
+ }
+ mgm128_hash_block(ctx, out);
+ in += MGM128_BLOCK_SIZE;
+ out += MGM128_BLOCK_SIZE;
+ len -= MGM128_BLOCK_SIZE;
+ }
+
+ if (len) {
+ (*ctx->block)(ctx->y, ctx->part, ctx->key);
+ mgm128_inc(ctx->y + MGM128_BLOCK_SIZE / 2, MGM128_BLOCK_SIZE / 2);
+ for (n = 0; n < len; n++) {
+ ctx->part[n] ^= *(in++);
+ *(out++) = ctx->part[n];
+ }
+ }
+
+ ctx->d_remain = len;
+
+ return 0;
+}
+
+int CRYPTO_mgm128_decrypt(MGM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len)
+{
+ unsigned int n;
+
+ /* Handle AAD remainder */
+ if (ctx->a_remain) {
+ memset(ctx->part + ctx->a_remain, 0, MGM128_BLOCK_SIZE - ctx->a_remain);
+ mgm128_hash_block(ctx, ctx->part);
+ ctx->a_remain = 0;
+ }
+
+ ctx->len[1] += len * 8;
+
+ n = ctx->d_remain;
+ if (n) {
+ while (n && len) {
+ u8 tmp = *(in++);
+ *(out++) = ctx->part[n] ^ tmp;
+ ctx->part[n] = tmp;
+ n = (n + 1) % MGM128_BLOCK_SIZE;
+ }
+ if (n == 0) {
+ mgm128_hash_block(ctx, ctx->part);
+ } else {
+ ctx->d_remain = n;
+ return 0;
+ }
+ }
+
+ while (len >= MGM128_BLOCK_SIZE) {
+ mgm128_hash_block(ctx, in);
+ (*ctx->block)(ctx->y, ctx->part, ctx->key);
+ mgm128_inc(ctx->y + MGM128_BLOCK_SIZE / 2, MGM128_BLOCK_SIZE / 2);
+ for (n = 0; n < MGM128_BLOCK_SIZE; n++) {
+ out[n] = ctx->part[n] ^ in[n];
+ }
+ in += MGM128_BLOCK_SIZE;
+ out += MGM128_BLOCK_SIZE;
+ len -= MGM128_BLOCK_SIZE;
+ }
+
+ if (len) {
+ (*ctx->block)(ctx->y, ctx->part, ctx->key);
+ mgm128_inc(ctx->y + MGM128_BLOCK_SIZE / 2, MGM128_BLOCK_SIZE / 2);
+ for (n = 0; n < len; n++) {
+ u8 tmp = *(in++);
+ *(out++) = ctx->part[n] ^ tmp;
+ ctx->part[n] = tmp;
+ }
+ }
+
+ ctx->d_remain = len;
+
+ return 0;
+}
+
+int CRYPTO_mgm128_finish(MGM128_CONTEXT *ctx,const unsigned char *tag,
+ size_t len)
+{
+ /* Handle AAD and data remainder */
+ if (ctx->a_remain) {
+ memset(ctx->part + ctx->a_remain, 0, MGM128_BLOCK_SIZE - ctx->a_remain);
+ mgm128_hash_block(ctx, ctx->part);
+ }
+
+ if (ctx->d_remain) {
+ memset(ctx->part + ctx->d_remain, 0, MGM128_BLOCK_SIZE - ctx->d_remain);
+ mgm128_hash_block(ctx, ctx->part);
+ }
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#ifndef BSWAP8
+#define BSWAP8(u) (u64)GETU32((unsigned char *)&u) << 32|GETU32(((unsigned char *)&u) + 4)
+#endif
+ ctx->len[0] = BSWAP8(ctx->len[0]);
+ ctx->len[1] = BSWAP8(ctx->len[1]);
+#endif
+ mgm128_hash_block(ctx, (unsigned char *)ctx->len);
+
+ (*ctx->block)((unsigned char *)ctx->sum, (unsigned char *)ctx->sum, ctx->key);
+
+ if (tag && len<=sizeof(ctx->sum))
+ return memcmp(ctx->sum, tag, len);
+ else
+ return -1;
+}
+
+void CRYPTO_mgm128_tag(MGM128_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+ CRYPTO_mgm128_finish(ctx, NULL, 0);
+ memcpy(tag, ctx->sum, len<=sizeof(ctx->sum)?len:sizeof(ctx->sum));
+}
diff --git a/src/lib/libcrypto/modes/modes.h b/src/lib/libcrypto/modes/modes.h
index 2344e944e..477d5eb52 100644
--- a/src/lib/libcrypto/modes/modes.h
+++ b/src/lib/libcrypto/modes/modes.h
@@ -139,6 +139,22 @@ typedef struct xts128_context XTS128_CONTEXT;
int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
const unsigned char *inp, unsigned char *out, size_t len, int enc);
+typedef struct mgm128_context MGM128_CONTEXT;
+
+void CRYPTO_mgm128_init(MGM128_CONTEXT *ctx,void *key,block128_f block);
+void CRYPTO_mgm128_setiv(MGM128_CONTEXT *ctx, const unsigned char *iv);
+int CRYPTO_mgm128_aad(MGM128_CONTEXT *ctx, const unsigned char *aad,
+ size_t len);
+int CRYPTO_mgm128_encrypt(MGM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len);
+int CRYPTO_mgm128_decrypt(MGM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len);
+int CRYPTO_mgm128_finish(MGM128_CONTEXT *ctx,const unsigned char *tag,
+ size_t len);
+void CRYPTO_mgm128_tag(MGM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+
typedef void (*block64_f)(const unsigned char in[8],
unsigned char out[8],
const void *key);
diff --git a/src/lib/libcrypto/modes/modes_lcl.h b/src/lib/libcrypto/modes/modes_lcl.h
index f8830e4de..e1bc05da5 100644
--- a/src/lib/libcrypto/modes/modes_lcl.h
+++ b/src/lib/libcrypto/modes/modes_lcl.h
@@ -108,4 +108,15 @@ struct ccm128_context {
void *key;
};
+struct mgm128_context {
+ u64 len[2]; /* aad and data len */
+ u64 sum[2];
+ u8 y[16], z[16], part[16];
+ block128_f block;
+ void *key;
+ unsigned int a_remain, d_remain;
+};
+
+#define MGM128_NONCE_LEN 16
+
__END_HIDDEN_DECLS
--
2.17.1

View file

@ -0,0 +1,378 @@
From 2b03c9ee4c27cceda26c18eaa462e88e42014a3e Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 21:54:20 +0300
Subject: [PATCH 44/87] modes: add support for 64-bit MGM mode
Add support for 64-bit MGM (Multilinear Galois Mode) defined in
draft-smyshlyaev-mgm.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/modes/mgm64.c | 306 ++++++++++++++++++++++++++++
src/lib/libcrypto/modes/modes.h | 16 ++
src/lib/libcrypto/modes/modes_lcl.h | 11 +
3 files changed, 333 insertions(+)
create mode 100644 src/lib/libcrypto/modes/mgm64.c
diff --git a/src/lib/libcrypto/modes/mgm64.c b/src/lib/libcrypto/modes/mgm64.c
new file mode 100644
index 000000000..071ab19d2
--- /dev/null
+++ b/src/lib/libcrypto/modes/mgm64.c
@@ -0,0 +1,306 @@
+/* $OpenBSD: mgm64.c,v 1.22 2018/01/24 23:03:37 kettenis Exp $ */
+/*
+ * Copyright (c) 2020 Dmitry Baryshkov <dbaryshkov@gmail.com>
+ *
+ * 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 <string.h>
+#include <machine/endian.h>
+
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+
+#define MGM64_BLOCK_SIZE 8
+#define MGM64_POLYNOMIAL U64(0x1b)
+
+static u64
+mgm64_gf_shift (const u64 x)
+{
+ long mask;
+
+ /* Shift uses big-endian representation. */
+#if BYTE_ORDER != LITTLE_ENDIAN
+ mask = - ((x >> 63) & 1);
+ return (x << 1) ^ (mask & (MGM64_POLYNOMIAL));
+#else /* ! WORDS_BIGENDIAN */
+#define RSHIFT_WORD(x) \
+ ((((x) & UINT64_C(0x7f7f7f7f7f7f7f7f)) << 1) \
+ | (((x) & UINT64_C(0x8080808080808000)) >> 15))
+ mask = - ((x >> 7) & 1);
+ return RSHIFT_WORD(x) ^ (mask & (MGM64_POLYNOMIAL << 56));
+# undef RSHIFT_WORD
+#endif /* ! WORDS_BIGENDIAN */
+}
+
+static void
+mgm64_gf_mul_sum(MGM64_CONTEXT *ctx, u64 x, const uint8_t *y)
+{
+ u64 V, Z;
+ unsigned i;
+
+ V = x;
+ Z = 0;
+
+ for (i = 0; i < MGM64_BLOCK_SIZE; i++)
+ {
+ uint8_t b = y[MGM64_BLOCK_SIZE - i - 1];
+ unsigned j;
+ for (j = 0; j < 8; j++, b >>= 1)
+ {
+ if (b & 1) {
+ Z ^= V;
+ }
+
+ V = mgm64_gf_shift(V);
+ }
+ }
+
+ ctx->sum ^= Z;
+}
+
+static inline void mgm64_inc(unsigned char *counter, u32 n)
+{
+ u8 c;
+
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c) return;
+ } while (n);
+}
+
+void mgm64_hash_block(MGM64_CONTEXT *ctx, const u8 *data)
+{
+ union {u64 u; u8 c[MGM64_BLOCK_SIZE]; } tmp;
+
+ (*ctx->block)(ctx->z, tmp.c, ctx->key);
+ mgm64_gf_mul_sum(ctx, tmp.u, data);
+ mgm64_inc(ctx->z, MGM64_BLOCK_SIZE / 2);
+}
+
+void CRYPTO_mgm64_init(MGM64_CONTEXT *ctx, void *key, block64_f block)
+{
+ memset(ctx,0,sizeof(*ctx));
+ ctx->block = block;
+ ctx->key = key;
+}
+
+void CRYPTO_mgm64_setiv(MGM64_CONTEXT *ctx, const unsigned char *iv)
+{
+ memcpy(ctx->y, iv, MGM64_NONCE_LEN);
+ memcpy(ctx->z, iv, MGM64_NONCE_LEN);
+
+ ctx->y[0] &= 0x7f;
+ ctx->z[0] |= 0x80;
+
+ (*ctx->block)(ctx->y, ctx->y, ctx->key);
+ (*ctx->block)(ctx->z, ctx->z, ctx->key);
+
+ ctx->sum = 0;
+ memset(ctx->len, 0, MGM64_BLOCK_SIZE);
+}
+
+int CRYPTO_mgm64_aad(MGM64_CONTEXT *ctx, const unsigned char *aad,
+ size_t len)
+{
+ unsigned int n;
+
+ if (ctx->len[1])
+ return -2;
+
+ ctx->len[0] += len * 8;
+
+ n = ctx->a_remain;
+ if (n) {
+ while (n && len) {
+ ctx->part[n] = *(aad++);
+ --len;
+ n = (n + 1) % MGM64_BLOCK_SIZE;
+ }
+ if (n == 0) {
+ mgm64_hash_block(ctx, ctx->part);
+ } else {
+ ctx->a_remain = n;
+ return 0;
+ }
+ }
+
+ while (len >= MGM64_BLOCK_SIZE) {
+ mgm64_hash_block(ctx, aad);
+ aad += MGM64_BLOCK_SIZE;
+ len -= MGM64_BLOCK_SIZE;
+ }
+
+ if (len)
+ memcpy(ctx->part, aad, len);
+
+ ctx->a_remain = len;
+ return 0;
+}
+
+int CRYPTO_mgm64_encrypt(MGM64_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len)
+{
+ unsigned int n;
+
+ /* Handle AAD remainder */
+ if (ctx->a_remain) {
+ memset(ctx->part + ctx->a_remain, 0, MGM64_BLOCK_SIZE - ctx->a_remain);
+ mgm64_hash_block(ctx, ctx->part);
+ ctx->a_remain = 0;
+ }
+
+ ctx->len[1] += len * 8;
+
+ n = ctx->d_remain;
+ if (n) {
+ while (n && len) {
+ ctx->part[n] ^= *(in++);
+ *(out++) = ctx->part[n];
+ --len;
+ n = (n + 1) % MGM64_BLOCK_SIZE;
+ }
+ if (n == 0) {
+ mgm64_hash_block(ctx, ctx->part);
+ } else {
+ ctx->d_remain = n;
+ return 0;
+ }
+ }
+
+ while (len >= MGM64_BLOCK_SIZE) {
+ (*ctx->block)(ctx->y, ctx->part, ctx->key);
+ mgm64_inc(ctx->y + MGM64_BLOCK_SIZE / 2, MGM64_BLOCK_SIZE / 2);
+ for (n = 0; n < MGM64_BLOCK_SIZE; n++) {
+ out[n] = ctx->part[n] ^ in[n];
+ }
+ mgm64_hash_block(ctx, out);
+ in += MGM64_BLOCK_SIZE;
+ out += MGM64_BLOCK_SIZE;
+ len -= MGM64_BLOCK_SIZE;
+ }
+
+ if (len) {
+ (*ctx->block)(ctx->y, ctx->part, ctx->key);
+ mgm64_inc(ctx->y + MGM64_BLOCK_SIZE / 2, MGM64_BLOCK_SIZE / 2);
+ for (n = 0; n < len; n++) {
+ ctx->part[n] ^= *(in++);
+ *(out++) = ctx->part[n];
+ }
+ }
+
+ ctx->d_remain = len;
+
+ return 0;
+}
+
+int CRYPTO_mgm64_decrypt(MGM64_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len)
+{
+ unsigned int n;
+
+ /* Handle AAD remainder */
+ if (ctx->a_remain) {
+ memset(ctx->part + ctx->a_remain, 0, MGM64_BLOCK_SIZE - ctx->a_remain);
+ mgm64_hash_block(ctx, ctx->part);
+ ctx->a_remain = 0;
+ }
+
+ ctx->len[1] += len * 8;
+
+ n = ctx->d_remain;
+ if (n) {
+ while (n && len) {
+ u8 tmp = *(in++);
+ *(out++) = ctx->part[n] ^ tmp;
+ ctx->part[n] = tmp;
+ n = (n + 1) % MGM64_BLOCK_SIZE;
+ }
+ if (n == 0) {
+ mgm64_hash_block(ctx, ctx->part);
+ } else {
+ ctx->d_remain = n;
+ return 0;
+ }
+ }
+
+ while (len >= MGM64_BLOCK_SIZE) {
+ mgm64_hash_block(ctx, in);
+ (*ctx->block)(ctx->y, ctx->part, ctx->key);
+ mgm64_inc(ctx->y + MGM64_BLOCK_SIZE / 2, MGM64_BLOCK_SIZE / 2);
+ for (n = 0; n < MGM64_BLOCK_SIZE; n++) {
+ out[n] = ctx->part[n] ^ in[n];
+ }
+ in += MGM64_BLOCK_SIZE;
+ out += MGM64_BLOCK_SIZE;
+ len -= MGM64_BLOCK_SIZE;
+ }
+
+ if (len) {
+ (*ctx->block)(ctx->y, ctx->part, ctx->key);
+ mgm64_inc(ctx->y + MGM64_BLOCK_SIZE / 2, MGM64_BLOCK_SIZE / 2);
+ for (n = 0; n < len; n++) {
+ u8 tmp = *(in++);
+ *(out++) = ctx->part[n] ^ tmp;
+ ctx->part[n] = tmp;
+ }
+ }
+
+ ctx->d_remain = len;
+
+ return 0;
+}
+
+int CRYPTO_mgm64_finish(MGM64_CONTEXT *ctx,const unsigned char *tag,
+ size_t len)
+{
+ /* Handle AAD and data remainder */
+ if (ctx->a_remain) {
+ memset(ctx->part + ctx->a_remain, 0, MGM64_BLOCK_SIZE - ctx->a_remain);
+ mgm64_hash_block(ctx, ctx->part);
+ }
+
+ if (ctx->d_remain) {
+ memset(ctx->part + ctx->d_remain, 0, MGM64_BLOCK_SIZE - ctx->d_remain);
+ mgm64_hash_block(ctx, ctx->part);
+ }
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef BSWAP4
+ ctx->len[0] = BSWAP4(ctx->len[0]);
+ ctx->len[1] = BSWAP4(ctx->len[1]);
+#else
+ ctx->len[0] = GETU32((unsigned char *)&ctx->len[0]);
+ ctx->len[1] = GETU32((unsigned char *)&ctx->len[1]);
+#endif
+#endif
+ mgm64_hash_block(ctx, (unsigned char *)ctx->len);
+
+ (*ctx->block)((unsigned char *)&ctx->sum, (unsigned char *)&ctx->sum, ctx->key);
+
+ if (tag && len<=sizeof(ctx->sum))
+ return memcmp(&ctx->sum, tag, len);
+ else
+ return -1;
+}
+
+void CRYPTO_mgm64_tag(MGM64_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+ CRYPTO_mgm64_finish(ctx, NULL, 0);
+ memcpy(tag, &ctx->sum, len<=sizeof(ctx->sum)?len:sizeof(ctx->sum));
+}
diff --git a/src/lib/libcrypto/modes/modes.h b/src/lib/libcrypto/modes/modes.h
index 477d5eb52..4d238bfeb 100644
--- a/src/lib/libcrypto/modes/modes.h
+++ b/src/lib/libcrypto/modes/modes.h
@@ -181,6 +181,22 @@ void CRYPTO_cfb64_encrypt(const unsigned char *in, unsigned char *out,
unsigned char ivec[8], int *num,
int enc, block64_f block);
+typedef struct mgm64_context MGM64_CONTEXT;
+
+void CRYPTO_mgm64_init(MGM64_CONTEXT *ctx,void *key,block64_f block);
+void CRYPTO_mgm64_setiv(MGM64_CONTEXT *ctx, const unsigned char *iv);
+int CRYPTO_mgm64_aad(MGM64_CONTEXT *ctx, const unsigned char *aad,
+ size_t len);
+int CRYPTO_mgm64_encrypt(MGM64_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len);
+int CRYPTO_mgm64_decrypt(MGM64_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len);
+int CRYPTO_mgm64_finish(MGM64_CONTEXT *ctx,const unsigned char *tag,
+ size_t len);
+void CRYPTO_mgm64_tag(MGM64_CONTEXT *ctx, unsigned char *tag, size_t len);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/libcrypto/modes/modes_lcl.h b/src/lib/libcrypto/modes/modes_lcl.h
index e1bc05da5..cafcea167 100644
--- a/src/lib/libcrypto/modes/modes_lcl.h
+++ b/src/lib/libcrypto/modes/modes_lcl.h
@@ -119,4 +119,15 @@ struct mgm128_context {
#define MGM128_NONCE_LEN 16
+struct mgm64_context {
+ u32 len[2]; /* aad and data len */
+ u64 sum;
+ u8 y[8], z[8], part[8];
+ block64_f block;
+ void *key;
+ unsigned int a_remain, d_remain;
+};
+
+#define MGM64_NONCE_LEN 8
+
__END_HIDDEN_DECLS
--
2.17.1

View file

@ -0,0 +1,258 @@
From bdeea3d404c165fc266a1be7278db3865652b509 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 21:56:51 +0300
Subject: [PATCH 45/87] gost: add kuznyechik-mgm support
Add EVP_AEAD interface for supporting kuznyechik cipher in MGM mode.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/evp/e_kuznyechik.c | 161 +++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 5 +
src/regress/lib/libcrypto/aead/aeadtest.c | 6 +
src/regress/lib/libcrypto/aead/aeadtests.txt | 9 ++
5 files changed, 182 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index 287c86d2c..aff725bd4 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1618,6 +1618,7 @@ EVP_add_digest
EVP_aead_aes_128_gcm
EVP_aead_aes_256_gcm
EVP_aead_chacha20_poly1305
+EVP_aead_kuznyechik_mgm
EVP_aead_xchacha20_poly1305
EVP_aes_128_cbc
EVP_aes_128_cbc_hmac_sha1
diff --git a/src/lib/libcrypto/evp/e_kuznyechik.c b/src/lib/libcrypto/evp/e_kuznyechik.c
index 5fd53aff6..88ecef8e5 100644
--- a/src/lib/libcrypto/evp/e_kuznyechik.c
+++ b/src/lib/libcrypto/evp/e_kuznyechik.c
@@ -26,6 +26,7 @@
#include <openssl/modes.h>
#include <openssl/gost.h>
#include "evp_locl.h"
+#include "modes_lcl.h"
typedef struct {
KUZNYECHIK_KEY ks;
@@ -199,4 +200,164 @@ BLOCK_CIPHER_def1(kuznyechik, ctr_acpkm, ctr_acpkm, CTR, EVP_KUZNYECHIK_CTX,
kuznyechik_ctr_acpkm_get_asn1_params,
kuznyechik_acpkm_ctl)
+#define EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN 16
+
+struct aead_kuznyechik_mgm_ctx {
+ KUZNYECHIK_KEY ks;
+ MGM128_CONTEXT mgm;
+ unsigned char tag_len;
+};
+
+static void
+kuznyechik_mgm_set_key(KUZNYECHIK_KEY *kuznyechik_key, MGM128_CONTEXT *mgm_ctx,
+ const unsigned char *key, size_t key_len)
+{
+ Kuznyechik_set_key(kuznyechik_key, key, 1);
+ CRYPTO_mgm128_init(mgm_ctx, kuznyechik_key, (block128_f)Kuznyechik_encrypt);
+}
+
+static int
+aead_kuznyechik_mgm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
+ size_t tag_len)
+{
+ struct aead_kuznyechik_mgm_ctx *mgm_ctx;
+ const size_t key_bits = key_len * 8;
+
+ /* EVP_AEAD_CTX_init should catch this. */
+ if (key_bits != 256) {
+ EVPerror(EVP_R_BAD_KEY_LENGTH);
+ return 0;
+ }
+
+ if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
+ tag_len = EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN;
+
+ if (tag_len > EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN) {
+ EVPerror(EVP_R_TAG_TOO_LARGE);
+ return 0;
+ }
+
+ if ((mgm_ctx = calloc(1, sizeof(struct aead_kuznyechik_mgm_ctx))) == NULL)
+ return 0;
+
+ kuznyechik_mgm_set_key(&mgm_ctx->ks, &mgm_ctx->mgm, key, key_len);
+
+ mgm_ctx->tag_len = tag_len;
+ ctx->aead_state = mgm_ctx;
+
+ return 1;
+}
+
+static void
+aead_kuznyechik_mgm_cleanup(EVP_AEAD_CTX *ctx)
+{
+ struct aead_kuznyechik_mgm_ctx *mgm_ctx = ctx->aead_state;
+
+ freezero(mgm_ctx, sizeof(*mgm_ctx));
+}
+
+static int
+aead_kuznyechik_mgm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
+ size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
+ const unsigned char *in, size_t in_len, const unsigned char *ad,
+ size_t ad_len)
+{
+ const struct aead_kuznyechik_mgm_ctx *mgm_ctx = ctx->aead_state;
+ MGM128_CONTEXT mgm;
+ size_t bulk = 0;
+
+ if (max_out_len < in_len + mgm_ctx->tag_len) {
+ EVPerror(EVP_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (nonce_len != MGM128_NONCE_LEN) {
+ EVPerror(EVP_R_IV_TOO_LARGE);
+ return 0;
+ }
+
+ memcpy(&mgm, &mgm_ctx->mgm, sizeof(mgm));
+ CRYPTO_mgm128_setiv(&mgm, nonce);
+
+ if (ad_len > 0 && CRYPTO_mgm128_aad(&mgm, ad, ad_len))
+ return 0;
+
+ if (CRYPTO_mgm128_encrypt(&mgm, in + bulk, out + bulk,
+ in_len - bulk))
+ return 0;
+
+ CRYPTO_mgm128_tag(&mgm, out + in_len, mgm_ctx->tag_len);
+ *out_len = in_len + mgm_ctx->tag_len;
+
+ return 1;
+}
+
+static int
+aead_kuznyechik_mgm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
+ size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
+ const unsigned char *in, size_t in_len, const unsigned char *ad,
+ size_t ad_len)
+{
+ const struct aead_kuznyechik_mgm_ctx *mgm_ctx = ctx->aead_state;
+ unsigned char tag[EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN];
+ MGM128_CONTEXT mgm;
+ size_t plaintext_len;
+ size_t bulk = 0;
+
+ if (in_len < mgm_ctx->tag_len) {
+ EVPerror(EVP_R_BAD_DECRYPT);
+ return 0;
+ }
+
+ plaintext_len = in_len - mgm_ctx->tag_len;
+
+ if (max_out_len < plaintext_len) {
+ EVPerror(EVP_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (nonce_len != MGM128_NONCE_LEN) {
+ EVPerror(EVP_R_IV_TOO_LARGE);
+ return 0;
+ }
+
+ memcpy(&mgm, &mgm_ctx->mgm, sizeof(mgm));
+ CRYPTO_mgm128_setiv(&mgm, nonce);
+
+ if (CRYPTO_mgm128_aad(&mgm, ad, ad_len))
+ return 0;
+
+ if (CRYPTO_mgm128_decrypt(&mgm, in + bulk, out + bulk,
+ in_len - bulk - mgm_ctx->tag_len))
+ return 0;
+
+ CRYPTO_mgm128_tag(&mgm, tag, mgm_ctx->tag_len);
+ if (timingsafe_memcmp(tag, in + plaintext_len, mgm_ctx->tag_len) != 0) {
+ EVPerror(EVP_R_BAD_DECRYPT);
+ return 0;
+ }
+
+ *out_len = plaintext_len;
+
+ return 1;
+}
+
+static const EVP_AEAD aead_kuznyechik_mgm = {
+ .key_len = 32,
+ .nonce_len = 16,
+ .overhead = EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN,
+ .max_tag_len = EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN,
+
+ .init = aead_kuznyechik_mgm_init,
+ .cleanup = aead_kuznyechik_mgm_cleanup,
+ .seal = aead_kuznyechik_mgm_seal,
+ .open = aead_kuznyechik_mgm_open,
+};
+
+const EVP_AEAD *
+EVP_aead_kuznyechik_mgm(void)
+{
+ return &aead_kuznyechik_mgm;
+}
+
#endif
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 1ef416041..3725dd17c 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1289,6 +1289,11 @@ const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
const EVP_AEAD *EVP_aead_xchacha20_poly1305(void);
#endif
+#if !defined(OPENSSL_NO_GOST)
+/* EVP_aead_kuznyechik_mgm is Kuznyechik in Multilinear Galois Mode. */
+const EVP_AEAD *EVP_aead_kuznyechik_mgm(void);
+#endif
+
/* EVP_AEAD_key_length returns the length of the keys used. */
size_t EVP_AEAD_key_length(const EVP_AEAD *aead);
diff --git a/src/regress/lib/libcrypto/aead/aeadtest.c b/src/regress/lib/libcrypto/aead/aeadtest.c
index 1b144c261..6f843e31c 100644
--- a/src/regress/lib/libcrypto/aead/aeadtest.c
+++ b/src/regress/lib/libcrypto/aead/aeadtest.c
@@ -143,6 +143,12 @@ aead_from_name(const EVP_AEAD **aead, const char *name)
*aead = EVP_aead_xchacha20_poly1305();
#else
fprintf(stderr, "No xchacha20-poly1305 support.\n");
+#endif
+ } else if (strcmp(name, "kuznyechik-mgm") == 0) {
+#ifndef OPENSSL_NO_GOST
+ *aead = EVP_aead_kuznyechik_mgm();
+#else
+ fprintf(stderr, "No kuznyechik-MGM support.\n");
#endif
} else {
fprintf(stderr, "Unknown AEAD: %s\n", name);
diff --git a/src/regress/lib/libcrypto/aead/aeadtests.txt b/src/regress/lib/libcrypto/aead/aeadtests.txt
index 4ca47303b..d2d4e54f7 100644
--- a/src/regress/lib/libcrypto/aead/aeadtests.txt
+++ b/src/regress/lib/libcrypto/aead/aeadtests.txt
@@ -84,3 +84,12 @@ AD: 50515253c0c1c2c3c4c5c6c7
CT: bd6d179d3e83d43b9576579493c0e939572a1700252bfaccbed2902c21396cbb731c7f1b0b4aa6440bf3a82f4eda7e39ae64c6708c54c216cb96b72e1213b4522f8c9ba40db5d945b11b69b982c1bb9e3f3fac2bc369488f76b2383565d3fff921f9664c97637da9768812f615c68b13b52e
TAG: c0875924c1c7987947deafd8780acf49
+# draft-smyshlyaev-mgm-17
+AEAD: kuznyechik-mgm
+KEY: 8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef
+NONCE: 1122334455667700ffeeddccbbaa9988
+IN: 1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011aabbcc
+AD: 0202020202020202010101010101010104040404040404040303030303030303ea0505050505050505
+CT: a9757b8147956e9055b8a33de89f42fc8075d2212bf9fd5bd3f7069aadc16b39497ab15915a6ba85936b5d0ea9f6851cc60c14d4d3f883d0ab94420695c76deb2c7552
+TAG: cf5d656f40c34f5c46e8bb0e29fcdb4c
+
--
2.17.1

View file

@ -0,0 +1,254 @@
From 58d19972ccd8d8857633a578a3cfb10e6ae10d26 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 21:56:51 +0300
Subject: [PATCH 46/87] gost: add magma-mgm support
Add EVP_AEAD interface for supporting magma cipher in MGM mode.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/evp/e_magma.c | 160 +++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 2 +
src/regress/lib/libcrypto/aead/aeadtest.c | 6 +
src/regress/lib/libcrypto/aead/aeadtests.txt | 9 ++
5 files changed, 178 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index aff725bd4..56169f990 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1619,6 +1619,7 @@ EVP_aead_aes_128_gcm
EVP_aead_aes_256_gcm
EVP_aead_chacha20_poly1305
EVP_aead_kuznyechik_mgm
+EVP_aead_magma_mgm
EVP_aead_xchacha20_poly1305
EVP_aes_128_cbc
EVP_aes_128_cbc_hmac_sha1
diff --git a/src/lib/libcrypto/evp/e_magma.c b/src/lib/libcrypto/evp/e_magma.c
index 0311e04b1..3d3083b95 100644
--- a/src/lib/libcrypto/evp/e_magma.c
+++ b/src/lib/libcrypto/evp/e_magma.c
@@ -26,6 +26,7 @@
#include <openssl/modes.h>
#include <openssl/gost.h>
#include "evp_locl.h"
+#include "modes_lcl.h"
typedef struct {
MAGMA_KEY ks;
@@ -193,4 +194,163 @@ BLOCK_CIPHER_def1(magma, ctr_acpkm, ctr_acpkm, CTR, EVP_MAGMA_CTX,
magma_ctr_acpkm_get_asn1_params,
magma_acpkm_ctl)
+#define EVP_AEAD_MAGMA_MGM_TAG_LEN 16
+
+struct aead_magma_mgm_ctx {
+ MAGMA_KEY ks;
+ MGM64_CONTEXT mgm;
+ unsigned char tag_len;
+};
+
+static void
+magma_mgm_set_key(MAGMA_KEY *magma_key, MGM64_CONTEXT *mgm_ctx,
+ const unsigned char *key, size_t key_len)
+{
+ Magma_set_key(magma_key, key);
+ CRYPTO_mgm64_init(mgm_ctx, magma_key, (block64_f)Magma_encrypt);
+}
+
+static int
+aead_magma_mgm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
+ size_t tag_len)
+{
+ struct aead_magma_mgm_ctx *mgm_ctx;
+ const size_t key_bits = key_len * 8;
+
+ /* EVP_AEAD_CTX_init should catch this. */
+ if (key_bits != 256) {
+ EVPerror(EVP_R_BAD_KEY_LENGTH);
+ return 0;
+ }
+
+ if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
+ tag_len = EVP_AEAD_MAGMA_MGM_TAG_LEN;
+
+ if (tag_len > EVP_AEAD_MAGMA_MGM_TAG_LEN) {
+ EVPerror(EVP_R_TAG_TOO_LARGE);
+ return 0;
+ }
+
+ if ((mgm_ctx = calloc(1, sizeof(struct aead_magma_mgm_ctx))) == NULL)
+ return 0;
+
+ magma_mgm_set_key(&mgm_ctx->ks, &mgm_ctx->mgm, key, key_len);
+
+ mgm_ctx->tag_len = tag_len;
+ ctx->aead_state = mgm_ctx;
+
+ return 1;
+}
+
+static void
+aead_magma_mgm_cleanup(EVP_AEAD_CTX *ctx)
+{
+ struct aead_magma_mgm_ctx *mgm_ctx = ctx->aead_state;
+
+ freezero(mgm_ctx, sizeof(*mgm_ctx));
+}
+
+static int
+aead_magma_mgm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
+ size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
+ const unsigned char *in, size_t in_len, const unsigned char *ad,
+ size_t ad_len)
+{
+ const struct aead_magma_mgm_ctx *mgm_ctx = ctx->aead_state;
+ MGM64_CONTEXT mgm;
+ size_t bulk = 0;
+
+ if (max_out_len < in_len + mgm_ctx->tag_len) {
+ EVPerror(EVP_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (nonce_len != MGM64_NONCE_LEN) {
+ EVPerror(EVP_R_IV_TOO_LARGE);
+ return 0;
+ }
+
+ memcpy(&mgm, &mgm_ctx->mgm, sizeof(mgm));
+ CRYPTO_mgm64_setiv(&mgm, nonce);
+
+ if (ad_len > 0 && CRYPTO_mgm64_aad(&mgm, ad, ad_len))
+ return 0;
+
+ if (CRYPTO_mgm64_encrypt(&mgm, in + bulk, out + bulk,
+ in_len - bulk))
+ return 0;
+
+ CRYPTO_mgm64_tag(&mgm, out + in_len, mgm_ctx->tag_len);
+ *out_len = in_len + mgm_ctx->tag_len;
+
+ return 1;
+}
+
+static int
+aead_magma_mgm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
+ size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
+ const unsigned char *in, size_t in_len, const unsigned char *ad,
+ size_t ad_len)
+{
+ const struct aead_magma_mgm_ctx *mgm_ctx = ctx->aead_state;
+ unsigned char tag[EVP_AEAD_MAGMA_MGM_TAG_LEN];
+ MGM64_CONTEXT mgm;
+ size_t plaintext_len;
+ size_t bulk = 0;
+
+ if (in_len < mgm_ctx->tag_len) {
+ EVPerror(EVP_R_BAD_DECRYPT);
+ return 0;
+ }
+
+ plaintext_len = in_len - mgm_ctx->tag_len;
+
+ if (max_out_len < plaintext_len) {
+ EVPerror(EVP_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (nonce_len != MGM64_NONCE_LEN) {
+ EVPerror(EVP_R_IV_TOO_LARGE);
+ return 0;
+ }
+
+ memcpy(&mgm, &mgm_ctx->mgm, sizeof(mgm));
+ CRYPTO_mgm64_setiv(&mgm, nonce);
+
+ if (CRYPTO_mgm64_aad(&mgm, ad, ad_len))
+ return 0;
+
+ if (CRYPTO_mgm64_decrypt(&mgm, in + bulk, out + bulk,
+ in_len - bulk - mgm_ctx->tag_len))
+ return 0;
+
+ CRYPTO_mgm64_tag(&mgm, tag, mgm_ctx->tag_len);
+ if (timingsafe_memcmp(tag, in + plaintext_len, mgm_ctx->tag_len) != 0) {
+ EVPerror(EVP_R_BAD_DECRYPT);
+ return 0;
+ }
+
+ *out_len = plaintext_len;
+
+ return 1;
+}
+
+static const EVP_AEAD aead_magma_mgm = {
+ .key_len = 32,
+ .nonce_len = 8,
+ .overhead = EVP_AEAD_MAGMA_MGM_TAG_LEN,
+ .max_tag_len = EVP_AEAD_MAGMA_MGM_TAG_LEN,
+
+ .init = aead_magma_mgm_init,
+ .cleanup = aead_magma_mgm_cleanup,
+ .seal = aead_magma_mgm_seal,
+ .open = aead_magma_mgm_open,
+};
+
+const EVP_AEAD *
+EVP_aead_magma_mgm(void)
+{
+ return &aead_magma_mgm;
+}
#endif
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 3725dd17c..88d9b1989 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1292,6 +1292,8 @@ const EVP_AEAD *EVP_aead_xchacha20_poly1305(void);
#if !defined(OPENSSL_NO_GOST)
/* EVP_aead_kuznyechik_mgm is Kuznyechik in Multilinear Galois Mode. */
const EVP_AEAD *EVP_aead_kuznyechik_mgm(void);
+/* EVP_aead_magma_mgm is Magma in Multilinear Galois Mode. */
+const EVP_AEAD *EVP_aead_magma_mgm(void);
#endif
/* EVP_AEAD_key_length returns the length of the keys used. */
diff --git a/src/regress/lib/libcrypto/aead/aeadtest.c b/src/regress/lib/libcrypto/aead/aeadtest.c
index 6f843e31c..37244931f 100644
--- a/src/regress/lib/libcrypto/aead/aeadtest.c
+++ b/src/regress/lib/libcrypto/aead/aeadtest.c
@@ -149,6 +149,12 @@ aead_from_name(const EVP_AEAD **aead, const char *name)
*aead = EVP_aead_kuznyechik_mgm();
#else
fprintf(stderr, "No kuznyechik-MGM support.\n");
+#endif
+ } else if (strcmp(name, "magma-mgm") == 0) {
+#ifndef OPENSSL_NO_GOST
+ *aead = EVP_aead_magma_mgm();
+#else
+ fprintf(stderr, "No magma-MGM support.\n");
#endif
} else {
fprintf(stderr, "Unknown AEAD: %s\n", name);
diff --git a/src/regress/lib/libcrypto/aead/aeadtests.txt b/src/regress/lib/libcrypto/aead/aeadtests.txt
index d2d4e54f7..86f5dac7e 100644
--- a/src/regress/lib/libcrypto/aead/aeadtests.txt
+++ b/src/regress/lib/libcrypto/aead/aeadtests.txt
@@ -93,3 +93,12 @@ AD: 0202020202020202010101010101010104040404040404040303030303030303ea0505050505
CT: a9757b8147956e9055b8a33de89f42fc8075d2212bf9fd5bd3f7069aadc16b39497ab15915a6ba85936b5d0ea9f6851cc60c14d4d3f883d0ab94420695c76deb2c7552
TAG: cf5d656f40c34f5c46e8bb0e29fcdb4c
+# Not defined in a draft, only in original R 1323565.1.026-2019
+AEAD: magma-mgm
+KEY: ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
+NONCE: 92def06b3c130a59
+IN: ffeeddccbbaa998811223344556677008899aabbcceeff0a001122334455667799aabbcceeff0a001122334455667788aabbcceeff0a00112233445566778899aabbcc
+AD: 01010101010101010202020202020202030303030303030304040404040404040505050505050505EA
+CT: c795066c5f9ea03b85113342459185ae1f2e00d6bf2b785d940470b8bb9c8e7d9a5dd3731f7ddc70ec27cb0ace6fa57670f65c646abb75d547aa37c3bcb5c34e03bb9c
+TAG: a7928069aa10fd10
+
--
2.17.1

View file

@ -0,0 +1,427 @@
From b4247b2de1624811aa03898b7f52d4c4dd2f0ac4 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 23:37:12 +0300
Subject: [PATCH 47/87] regress/evp: add simple test for AEAD ciphers
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 <dbaryshkov@gmail.com>
---
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 000000000..6d3970ee3
--- /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-core@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 <stdio.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/conf.h>
+
+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", &n) != 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);
+}
+
+static int
+test1_exit(int ec)
+{
+ exit(ec);
+ return(0); /* To keep some compilers quiet */
+}
+
+static int
+test_cipher(const char *cipher, const unsigned char *key, int kn,
+ const unsigned char *iv, int in,
+ const unsigned char *aad, int an,
+ const unsigned char *plaintext, int pn,
+ const unsigned char *ciphertext, int cn,
+ const unsigned char *tag, int tn,
+ int encdec)
+{
+ EVP_CIPHER_CTX ctx;
+ unsigned char out[4096];
+ const unsigned char *eiv;
+ int outl, outl2;
+
+ const EVP_CIPHER *c;
+
+ c = EVP_get_cipherbyname(cipher);
+ if (!c)
+ return 0;
+
+ printf("Testing cipher %s%s\n", EVP_CIPHER_name(c),
+ (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
+ hexdump(stdout, "Key",key,kn);
+ hexdump(stdout, "IV",iv,in);
+ hexdump(stdout, "AAD",aad,an);
+ hexdump(stdout, "Plaintext",plaintext,pn);
+ hexdump(stdout, "Ciphertext",ciphertext,cn);
+ hexdump(stdout, "Tag",tag,tn);
+
+ if (kn != c->key_len) {
+ fprintf(stderr, "Key length doesn't match, got %d expected %lu\n",kn,
+ (unsigned long)c->key_len);
+ test1_exit(1);
+ }
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
+ if (encdec != 0) {
+ eiv = iv;
+ if (EVP_CIPHER_mode(c) == EVP_CIPH_WRAP_MODE && in == 0)
+ eiv = NULL;
+ if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, eiv)) {
+ fprintf(stderr, "EncryptInit failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(2);
+ }
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+ if (!EVP_EncryptUpdate(&ctx, NULL, &outl, aad, an)) {
+ fprintf(stderr, "Encrypt failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(3);
+ }
+ if (!EVP_EncryptUpdate(&ctx, out, &outl, plaintext, pn)) {
+ fprintf(stderr, "Encrypt failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(4);
+ }
+ if (!EVP_EncryptFinal_ex(&ctx, out + outl, &outl2)) {
+ fprintf(stderr, "EncryptFinal failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(5);
+ }
+
+ if (outl + outl2 != cn) {
+ fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n",
+ outl + outl2, cn);
+ test1_exit(6);
+ }
+
+ if (memcmp(out, ciphertext, cn)) {
+ fprintf(stderr, "Ciphertext mismatch\n");
+ hexdump(stderr, "Got",out,cn);
+ hexdump(stderr, "Expected",ciphertext,cn);
+ test1_exit(7);
+ }
+
+ if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tn, out)) {
+ fprintf(stderr, "GET_TAG failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(8);
+ }
+
+ if (memcmp(out, tag, tn)) {
+ fprintf(stderr, "Ciphertext mismatch\n");
+ hexdump(stderr, "Got",out,tn);
+ hexdump(stderr, "Expected",tag,cn);
+ test1_exit(9);
+ }
+
+ }
+
+ if (encdec <= 0) {
+ eiv = iv;
+ if (EVP_CIPHER_mode(c) == EVP_CIPH_WRAP_MODE && in == 0)
+ eiv = NULL;
+ if (!EVP_DecryptInit_ex(&ctx, c,NULL, key, eiv)) {
+ fprintf(stderr, "DecryptInit failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(10);
+ }
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+ if (!EVP_DecryptUpdate(&ctx, NULL, &outl, aad, an)) {
+ fprintf(stderr, "Encrypt failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(10);
+ }
+ if (!EVP_DecryptUpdate(&ctx, out, &outl, ciphertext, cn)) {
+ fprintf(stderr, "Decrypt failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(12);
+ }
+
+ if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, tn, (void *)tag)) {
+ fprintf(stderr, "SET_TAG failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(13);
+ }
+
+ if (!EVP_DecryptFinal_ex(&ctx, out + outl, &outl2)) {
+ fprintf(stderr, "DecryptFinal failed\n");
+ ERR_print_errors_fp(stderr);
+ test1_exit(14);
+ }
+
+ if (outl + outl2 != pn) {
+ fprintf(stderr, "Plaintext length mismatch got %d expected %d\n",
+ outl + outl2, pn);
+ test1_exit(15);
+ }
+
+ if (memcmp(out, plaintext, pn)) {
+ fprintf(stderr, "Plaintext mismatch\n");
+ hexdump(stderr, "Got",out,pn);
+ hexdump(stderr, "Expected",plaintext,pn);
+ test1_exit(16);
+ }
+ }
+
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ printf("\n");
+
+ return 1;
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *szTestFile;
+ FILE *f;
+
+ if (argc != 2) {
+ fprintf(stderr, "%s <test file>\n",argv[0]);
+ exit(1);
+ }
+
+ szTestFile = argv[1];
+
+ f=fopen(szTestFile, "r");
+ if (!f) {
+ perror(szTestFile);
+ exit(2);
+ }
+
+ /* Load up the software EVP_CIPHER and EVP_MD definitions */
+ OpenSSL_add_all_ciphers();
+#ifndef OPENSSL_NO_ENGINE
+ /* Load all compiled-in ENGINEs */
+ ENGINE_load_builtin_engines();
+#endif
+#if 0
+ OPENSSL_config();
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ /* Register all available ENGINE implementations of ciphers and digests.
+ * This could perhaps be changed to "ENGINE_register_all_complete()"? */
+ ENGINE_register_all_ciphers();
+ /* If we add command-line options, this statement should be switchable.
+ * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if
+ * they weren't already initialised. */
+ /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
+#endif
+
+ for (;;) {
+ char line[8 * 1024];
+ char *p;
+ char *cipher;
+ unsigned char *iv, *key, *plaintext, *ciphertext, *aad, *tag;
+ int encdec;
+ int kn, in, pn, cn, an, tn;
+
+ if (!fgets((char *)line, sizeof line, f))
+ break;
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+ p = line;
+ cipher=sstrsep(&p, ":");
+ key=ustrsep(&p, ":");
+ iv=ustrsep(&p, ":");
+ aad=ustrsep(&p, ":");
+ plaintext=ustrsep(&p, ":");
+ ciphertext=ustrsep(&p, ":");
+ tag=ustrsep(&p, ":");
+ if (p[-1] == '\n') {
+ p[-1] = '\0';
+ encdec = -1;
+ } else {
+ encdec = atoi(sstrsep(&p, "\n"));
+ }
+
+ kn = convert(key);
+ in = convert(iv);
+ an = convert(aad);
+ pn = convert(plaintext);
+ cn = convert(ciphertext);
+ tn = convert(tag);
+
+ if (!test_cipher(cipher, key, kn, iv, in, aad, an, plaintext, pn, ciphertext, cn, tag, tn, encdec)) {
+#ifdef OPENSSL_NO_GOST
+ if (strstr(cipher, "magma") == cipher ||
+ strstr(cipher, "kuznyechik") == cipher) {
+ fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
+ continue;
+ }
+#endif
+ fprintf(stderr, "Can't find %s\n",cipher);
+ exit(3);
+ }
+ }
+ fclose(f);
+
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_cleanup();
+#endif
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ ERR_free_strings();
+ CRYPTO_mem_leaks_fp(stderr);
+
+ return 0;
+}
diff --git a/src/regress/lib/libcrypto/evp/evpaeadtests.txt b/src/regress/lib/libcrypto/evp/evpaeadtests.txt
new file mode 100644
index 000000000..68156e7a5
--- /dev/null
+++ b/src/regress/lib/libcrypto/evp/evpaeadtests.txt
@@ -0,0 +1,14 @@
+# $OpenBSD: evptests.txt,v 1.9 2020/01/26 03:31:40 tb Exp $
+#cipher:key:iv:aad:plaintext:ciphertext:tag:0/1(decrypt/encrypt)
+
+aes-128-gcm:013FE00B5F11BE7F866D0CBBC55A7A90:7CFDE9F9E33724C68932D612:84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005:::217867E50C2DAD74C28C3B50ABDF695A:1
+aes-128-gcm:013FE00B5F11BE7F866D0CBBC55A7A90:7CFDE9F9E33724C68932D612:84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005:::217867E50C2DAD74C28C3B50ABDF695A:0
+
+aes-256-gcm:83C093B58DE7FFE1C0DA926AC43FB3609AC1C80FEE1B624497EF942E2F79A823:7CFDE9F9E33724C68932D612:84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005:::6EE160E8FAECA4B36C86B234920CA975:1
+aes-256-gcm:83C093B58DE7FFE1C0DA926AC43FB3609AC1C80FEE1B624497EF942E2F79A823:7CFDE9F9E33724C68932D612:84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005:::6EE160E8FAECA4B36C86B234920CA975:0
+
+aes-128-gcm:88EE087FD95DA9FBF6725AA9D757B0CD:7AE8E2CA4EC500012E58495C:68F2E77696CE7AE8E2CA4EC588E54D002E58495C:08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008:C31F53D99E5687F7365119B832D2AAE70741D593F1F9E2AB3455779B078EB8FEACDFEC1F8E3E5277F8180B43361F6512ADB16D2E38548A2C719DBA7228D840:88F8757ADB8AA788D8F65AD668BE70E7:1
+aes-128-gcm:88EE087FD95DA9FBF6725AA9D757B0CD:7AE8E2CA4EC500012E58495C:68F2E77696CE7AE8E2CA4EC588E54D002E58495C:08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008:C31F53D99E5687F7365119B832D2AAE70741D593F1F9E2AB3455779B078EB8FEACDFEC1F8E3E5277F8180B43361F6512ADB16D2E38548A2C719DBA7228D840:88F8757ADB8AA788D8F65AD668BE70E7:0
+
+aes-256-gcm:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5:7AE8E2CA4EC500012E58495C:68F2E77696CE7AE8E2CA4EC588E54D002E58495C:08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008:BA8AE31BC506486D6873E4FCE460E7DC57591FF00611F31C3834FE1C04AD80B66803AFCF5B27E6333FA67C99DA47C2F0CED68D531BD741A943CFF7A6713BD0:2611CD7DAA01D61C5C886DC1A8170107:1
+aes-256-gcm:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5:7AE8E2CA4EC500012E58495C:68F2E77696CE7AE8E2CA4EC588E54D002E58495C:08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008:BA8AE31BC506486D6873E4FCE460E7DC57591FF00611F31C3834FE1C04AD80B66803AFCF5B27E6333FA67C99DA47C2F0CED68D531BD741A943CFF7A6713BD0:2611CD7DAA01D61C5C886DC1A8170107:0
--
2.17.1

View file

@ -0,0 +1,244 @@
From c9c7e6ed9d8c2deffdfe30c977ca91d2297177a9 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 23:44:15 +0300
Subject: [PATCH 48/87] evp: add EVP_CIPHER interface for kuznyechik-mgm
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/evp/c_all.c | 1 +
src/lib/libcrypto/evp/e_kuznyechik.c | 153 ++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 3 +
.../lib/libcrypto/evp/evpaeadtests.txt | 3 +
5 files changed, 161 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index 56169f990..d19720109 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1732,6 +1732,7 @@ EVP_kuznyechik_cfb64
EVP_kuznyechik_ctr
EVP_kuznyechik_ctr_acpkm
EVP_kuznyechik_ecb
+EVP_kuznyechik_mgm
EVP_kuznyechik_ofb
EVP_magma_cbc
EVP_magma_cfb64
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index c15be0c4f..586466eb6 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -241,6 +241,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_kuznyechik_ofb());
EVP_add_cipher(EVP_kuznyechik_ctr());
EVP_add_cipher(EVP_kuznyechik_ctr_acpkm());
+ EVP_add_cipher(EVP_kuznyechik_mgm());
#endif
#ifndef OPENSSL_NO_SM4
diff --git a/src/lib/libcrypto/evp/e_kuznyechik.c b/src/lib/libcrypto/evp/e_kuznyechik.c
index 88ecef8e5..d022db39c 100644
--- a/src/lib/libcrypto/evp/e_kuznyechik.c
+++ b/src/lib/libcrypto/evp/e_kuznyechik.c
@@ -202,6 +202,14 @@ BLOCK_CIPHER_def1(kuznyechik, ctr_acpkm, ctr_acpkm, CTR, EVP_KUZNYECHIK_CTX,
#define EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN 16
+typedef struct {
+ KUZNYECHIK_KEY ks; /* KUZNYECHIK key schedule to use */
+ MGM128_CONTEXT mgm;
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ int tag_len;
+} EVP_KUZNYECHIK_MGM_CTX;
+
struct aead_kuznyechik_mgm_ctx {
KUZNYECHIK_KEY ks;
MGM128_CONTEXT mgm;
@@ -216,6 +224,151 @@ kuznyechik_mgm_set_key(KUZNYECHIK_KEY *kuznyechik_key, MGM128_CONTEXT *mgm_ctx,
CRYPTO_mgm128_init(mgm_ctx, kuznyechik_key, (block128_f)Kuznyechik_encrypt);
}
+static int
+kuznyechik_mgm_cleanup(EVP_CIPHER_CTX *c)
+{
+ EVP_KUZNYECHIK_MGM_CTX *gctx = c->cipher_data;
+
+ explicit_bzero(gctx, sizeof(*gctx));
+ return 1;
+}
+
+static int
+kuznyechik_mgm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_KUZNYECHIK_MGM_CTX *gctx = c->cipher_data;
+
+ switch (type) {
+ case EVP_CTRL_INIT:
+ gctx->key_set = 0;
+ gctx->iv_set = 0;
+ gctx->tag_len = -1;
+ return 1;
+
+ case EVP_CTRL_MGM_SET_TAG:
+ if (arg <= 0 || arg > 16 || c->encrypt)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->tag_len = arg;
+ return 1;
+
+ case EVP_CTRL_MGM_GET_TAG:
+ if (arg <= 0 || arg > 16 || !c->encrypt || gctx->tag_len < 0)
+ return 0;
+ memcpy(ptr, c->buf, arg);
+ return 1;
+
+ case EVP_CTRL_COPY:
+ {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_KUZNYECHIK_MGM_CTX *gctx_out = out->cipher_data;
+
+ if (gctx->mgm.key) {
+ if (gctx->mgm.key != &gctx->ks)
+ return 0;
+ gctx_out->mgm.key = &gctx_out->ks;
+ }
+
+ return 1;
+ }
+
+ default:
+ return -1;
+
+ }
+}
+
+static int
+kuznyechik_mgm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_KUZNYECHIK_MGM_CTX *gctx = ctx->cipher_data;
+
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ kuznyechik_mgm_set_key(&gctx->ks, &gctx->mgm, key, ctx->key_len);
+
+ /* If we have an iv can set it directly, otherwise use
+ * saved IV.
+ */
+ if (gctx->iv_set)
+ iv = ctx->iv;
+ if (iv) {
+ CRYPTO_mgm128_setiv(&gctx->mgm, iv);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_mgm128_setiv(&gctx->mgm, iv);
+ else
+ memcpy(ctx->iv, iv, ctx->cipher->iv_len);
+ gctx->iv_set = 1;
+ }
+ return 1;
+}
+
+static int
+kuznyechik_mgm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_KUZNYECHIK_MGM_CTX *gctx = ctx->cipher_data;
+
+ /* If not set up, return error */
+ if (!gctx->key_set)
+ return -1;
+
+ if (!gctx->iv_set)
+ return -1;
+
+ if (in) {
+ if (out == NULL) {
+ if (CRYPTO_mgm128_aad(&gctx->mgm, in, len))
+ return -1;
+ } else if (ctx->encrypt) {
+ if (CRYPTO_mgm128_encrypt(&gctx->mgm, in, out, len))
+ return -1;
+ } else {
+ if (CRYPTO_mgm128_decrypt(&gctx->mgm, in, out, len))
+ return -1;
+ }
+ return len;
+ } else {
+ if (!ctx->encrypt) {
+ if (gctx->tag_len < 0)
+ return -1;
+ if (CRYPTO_mgm128_finish(&gctx->mgm, ctx->buf, gctx->tag_len) != 0)
+ return -1;
+ gctx->iv_set = 0;
+ return 0;
+ }
+ CRYPTO_mgm128_tag(&gctx->mgm, ctx->buf, 16);
+ gctx->tag_len = 16;
+
+ /* Don't reuse the IV */
+ gctx->iv_set = 0;
+ return 0;
+ }
+
+}
+
+#define CUSTOM_FLAGS \
+ ( EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV | \
+ EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | \
+ EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY )
+
+#define NID_kuznyechik_mgm NID_id_tc26_cipher_gostr3412_2015_kuznyechik_mgm
+
+BLOCK_CIPHER_def1(kuznyechik, mgm, mgm, GCM, EVP_KUZNYECHIK_MGM_CTX,
+ NID_kuznyechik, 1, 32, 16,
+ EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS,
+ kuznyechik_mgm_init_key, kuznyechik_mgm_cleanup,
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ kuznyechik_mgm_ctrl)
+
static int
aead_kuznyechik_mgm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
size_t tag_len)
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 88d9b1989..334ce1cd3 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -385,6 +385,8 @@ struct evp_cipher_st {
#define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG
#define EVP_CTRL_CCM_SET_L 0x14
#define EVP_CTRL_CCM_SET_MSGLEN 0x15
+#define EVP_CTRL_MGM_GET_TAG EVP_CTRL_GCM_GET_TAG
+#define EVP_CTRL_MGM_SET_TAG EVP_CTRL_GCM_SET_TAG
/* AEAD cipher deduces payload length and returns number of bytes
* required to store MAC and eventual padding. Subsequent call to
* EVP_Cipher even appends/verifies MAC.
@@ -860,6 +862,7 @@ const EVP_CIPHER *EVP_kuznyechik_cfb128(void);
const EVP_CIPHER *EVP_kuznyechik_ofb(void);
const EVP_CIPHER *EVP_kuznyechik_ctr(void);
const EVP_CIPHER *EVP_kuznyechik_ctr_acpkm(void);
+const EVP_CIPHER *EVP_kuznyechik_mgm(void);
#endif
#ifndef OPENSSL_NO_SM4
diff --git a/src/regress/lib/libcrypto/evp/evpaeadtests.txt b/src/regress/lib/libcrypto/evp/evpaeadtests.txt
index 68156e7a5..69ccd8c17 100644
--- a/src/regress/lib/libcrypto/evp/evpaeadtests.txt
+++ b/src/regress/lib/libcrypto/evp/evpaeadtests.txt
@@ -12,3 +12,6 @@ aes-128-gcm:88EE087FD95DA9FBF6725AA9D757B0CD:7AE8E2CA4EC500012E58495C:68F2E77696
aes-256-gcm:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5:7AE8E2CA4EC500012E58495C:68F2E77696CE7AE8E2CA4EC588E54D002E58495C:08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008:BA8AE31BC506486D6873E4FCE460E7DC57591FF00611F31C3834FE1C04AD80B66803AFCF5B27E6333FA67C99DA47C2F0CED68D531BD741A943CFF7A6713BD0:2611CD7DAA01D61C5C886DC1A8170107:1
aes-256-gcm:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5:7AE8E2CA4EC500012E58495C:68F2E77696CE7AE8E2CA4EC588E54D002E58495C:08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008:BA8AE31BC506486D6873E4FCE460E7DC57591FF00611F31C3834FE1C04AD80B66803AFCF5B27E6333FA67C99DA47C2F0CED68D531BD741A943CFF7A6713BD0:2611CD7DAA01D61C5C886DC1A8170107:0
+
+kuznyechik-mgm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1122334455667700ffeeddccbbaa9988:0202020202020202010101010101010104040404040404040303030303030303ea0505050505050505:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011aabbcc:a9757b8147956e9055b8a33de89f42fc8075d2212bf9fd5bd3f7069aadc16b39497ab15915a6ba85936b5d0ea9f6851cc60c14d4d3f883d0ab94420695c76deb2c7552:cf5d656f40c34f5c46e8bb0e29fcdb4c:1
+kuznyechik-mgm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1122334455667700ffeeddccbbaa9988:0202020202020202010101010101010104040404040404040303030303030303ea0505050505050505:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011aabbcc:a9757b8147956e9055b8a33de89f42fc8075d2212bf9fd5bd3f7069aadc16b39497ab15915a6ba85936b5d0ea9f6851cc60c14d4d3f883d0ab94420695c76deb2c7552:cf5d656f40c34f5c46e8bb0e29fcdb4c:0
--
2.17.1

View file

@ -0,0 +1,235 @@
From 10686e4b5c14cbff10d40e5ae630c0aa35aaa8fe Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 23:44:15 +0300
Subject: [PATCH 49/87] evp: add EVP_CIPHER interface for magma-mgm
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/evp/c_all.c | 1 +
src/lib/libcrypto/evp/e_magma.c | 153 ++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 1 +
.../lib/libcrypto/evp/evpaeadtests.txt | 3 +
5 files changed, 159 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index d19720109..3eda9f3bd 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1739,6 +1739,7 @@ EVP_magma_cfb64
EVP_magma_ctr
EVP_magma_ctr_acpkm
EVP_magma_ecb
+EVP_magma_mgm
EVP_magma_ofb
EVP_md4
EVP_md5
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index 586466eb6..6a60624d3 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -235,6 +235,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_magma_ofb());
EVP_add_cipher(EVP_magma_ctr());
EVP_add_cipher(EVP_magma_ctr_acpkm());
+ EVP_add_cipher(EVP_magma_mgm());
EVP_add_cipher(EVP_kuznyechik_ecb());
EVP_add_cipher(EVP_kuznyechik_cbc());
EVP_add_cipher(EVP_kuznyechik_cfb128());
diff --git a/src/lib/libcrypto/evp/e_magma.c b/src/lib/libcrypto/evp/e_magma.c
index 3d3083b95..ae78824eb 100644
--- a/src/lib/libcrypto/evp/e_magma.c
+++ b/src/lib/libcrypto/evp/e_magma.c
@@ -196,6 +196,14 @@ BLOCK_CIPHER_def1(magma, ctr_acpkm, ctr_acpkm, CTR, EVP_MAGMA_CTX,
#define EVP_AEAD_MAGMA_MGM_TAG_LEN 16
+typedef struct {
+ MAGMA_KEY ks; /* MAGMA key schedule to use */
+ MGM64_CONTEXT mgm;
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ int tag_len;
+} EVP_MAGMA_MGM_CTX;
+
struct aead_magma_mgm_ctx {
MAGMA_KEY ks;
MGM64_CONTEXT mgm;
@@ -210,6 +218,151 @@ magma_mgm_set_key(MAGMA_KEY *magma_key, MGM64_CONTEXT *mgm_ctx,
CRYPTO_mgm64_init(mgm_ctx, magma_key, (block64_f)Magma_encrypt);
}
+static int
+magma_mgm_cleanup(EVP_CIPHER_CTX *c)
+{
+ EVP_MAGMA_MGM_CTX *gctx = c->cipher_data;
+
+ explicit_bzero(gctx, sizeof(*gctx));
+ return 1;
+}
+
+static int
+magma_mgm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_MAGMA_MGM_CTX *gctx = c->cipher_data;
+
+ switch (type) {
+ case EVP_CTRL_INIT:
+ gctx->key_set = 0;
+ gctx->iv_set = 0;
+ gctx->tag_len = -1;
+ return 1;
+
+ case EVP_CTRL_MGM_SET_TAG:
+ if (arg <= 0 || arg > 8 || c->encrypt)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->tag_len = arg;
+ return 1;
+
+ case EVP_CTRL_MGM_GET_TAG:
+ if (arg <= 0 || arg > 8 || !c->encrypt || gctx->tag_len < 0)
+ return 0;
+ memcpy(ptr, c->buf, arg);
+ return 1;
+
+ case EVP_CTRL_COPY:
+ {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_MAGMA_MGM_CTX *gctx_out = out->cipher_data;
+
+ if (gctx->mgm.key) {
+ if (gctx->mgm.key != &gctx->ks)
+ return 0;
+ gctx_out->mgm.key = &gctx_out->ks;
+ }
+
+ return 1;
+ }
+
+ default:
+ return -1;
+
+ }
+}
+
+static int
+magma_mgm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_MAGMA_MGM_CTX *gctx = ctx->cipher_data;
+
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ magma_mgm_set_key(&gctx->ks, &gctx->mgm, key, ctx->key_len);
+
+ /* If we have an iv can set it directly, otherwise use
+ * saved IV.
+ */
+ if (gctx->iv_set)
+ iv = ctx->iv;
+ if (iv) {
+ CRYPTO_mgm64_setiv(&gctx->mgm, iv);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_mgm64_setiv(&gctx->mgm, iv);
+ else
+ memcpy(ctx->iv, iv, ctx->cipher->iv_len);
+ gctx->iv_set = 1;
+ }
+ return 1;
+}
+
+static int
+magma_mgm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_MAGMA_MGM_CTX *gctx = ctx->cipher_data;
+
+ /* If not set up, return error */
+ if (!gctx->key_set)
+ return -1;
+
+ if (!gctx->iv_set)
+ return -1;
+
+ if (in) {
+ if (out == NULL) {
+ if (CRYPTO_mgm64_aad(&gctx->mgm, in, len))
+ return -1;
+ } else if (ctx->encrypt) {
+ if (CRYPTO_mgm64_encrypt(&gctx->mgm, in, out, len))
+ return -1;
+ } else {
+ if (CRYPTO_mgm64_decrypt(&gctx->mgm, in, out, len))
+ return -1;
+ }
+ return len;
+ } else {
+ if (!ctx->encrypt) {
+ if (gctx->tag_len < 0)
+ return -1;
+ if (CRYPTO_mgm64_finish(&gctx->mgm, ctx->buf, gctx->tag_len) != 0)
+ return -1;
+ gctx->iv_set = 0;
+ return 0;
+ }
+ CRYPTO_mgm64_tag(&gctx->mgm, ctx->buf, 8);
+ gctx->tag_len = 8;
+
+ /* Don't reuse the IV */
+ gctx->iv_set = 0;
+ return 0;
+ }
+
+}
+
+#define CUSTOM_FLAGS \
+ ( EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV | \
+ EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | \
+ EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY )
+
+#define NID_magma_mgm NID_id_tc26_cipher_gostr3412_2015_magma_mgm
+
+BLOCK_CIPHER_def1(magma, mgm, mgm, GCM, EVP_MAGMA_MGM_CTX,
+ NID_magma, 1, 32, 8,
+ EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS,
+ magma_mgm_init_key, magma_mgm_cleanup,
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ magma_mgm_ctrl)
+
static int
aead_magma_mgm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
size_t tag_len)
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 334ce1cd3..50b157525 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -856,6 +856,7 @@ const EVP_CIPHER *EVP_magma_cfb64(void);
const EVP_CIPHER *EVP_magma_ofb(void);
const EVP_CIPHER *EVP_magma_ctr(void);
const EVP_CIPHER *EVP_magma_ctr_acpkm(void);
+const EVP_CIPHER *EVP_magma_mgm(void);
const EVP_CIPHER *EVP_kuznyechik_ecb(void);
const EVP_CIPHER *EVP_kuznyechik_cbc(void);
const EVP_CIPHER *EVP_kuznyechik_cfb128(void);
diff --git a/src/regress/lib/libcrypto/evp/evpaeadtests.txt b/src/regress/lib/libcrypto/evp/evpaeadtests.txt
index 69ccd8c17..9c8dd7142 100644
--- a/src/regress/lib/libcrypto/evp/evpaeadtests.txt
+++ b/src/regress/lib/libcrypto/evp/evpaeadtests.txt
@@ -15,3 +15,6 @@ aes-256-gcm:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5:7AE
kuznyechik-mgm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1122334455667700ffeeddccbbaa9988:0202020202020202010101010101010104040404040404040303030303030303ea0505050505050505:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011aabbcc:a9757b8147956e9055b8a33de89f42fc8075d2212bf9fd5bd3f7069aadc16b39497ab15915a6ba85936b5d0ea9f6851cc60c14d4d3f883d0ab94420695c76deb2c7552:cf5d656f40c34f5c46e8bb0e29fcdb4c:1
kuznyechik-mgm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1122334455667700ffeeddccbbaa9988:0202020202020202010101010101010104040404040404040303030303030303ea0505050505050505:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011aabbcc:a9757b8147956e9055b8a33de89f42fc8075d2212bf9fd5bd3f7069aadc16b39497ab15915a6ba85936b5d0ea9f6851cc60c14d4d3f883d0ab94420695c76deb2c7552:cf5d656f40c34f5c46e8bb0e29fcdb4c:0
+
+magma-mgm:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:92def06b3c130a59:01010101010101010202020202020202030303030303030304040404040404040505050505050505EA:ffeeddccbbaa998811223344556677008899aabbcceeff0a001122334455667799aabbcceeff0a001122334455667788aabbcceeff0a00112233445566778899aabbcc:c795066c5f9ea03b85113342459185ae1f2e00d6bf2b785d940470b8bb9c8e7d9a5dd3731f7ddc70ec27cb0ace6fa57670f65c646abb75d547aa37c3bcb5c34e03bb9c:a7928069aa10fd10:1
+magma-mgm:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:92def06b3c130a59:01010101010101010202020202020202030303030303030304040404040404040505050505050505EA:ffeeddccbbaa998811223344556677008899aabbcceeff0a001122334455667799aabbcceeff0a001122334455667788aabbcceeff0a00112233445566778899aabbcc:c795066c5f9ea03b85113342459185ae1f2e00d6bf2b785d940470b8bb9c8e7d9a5dd3731f7ddc70ec27cb0ace6fa57670f65c646abb75d547aa37c3bcb5c34e03bb9c:a7928069aa10fd10:0
--
2.17.1

View file

@ -0,0 +1,251 @@
From f3348e4b61f6cef3c31a7a62ede2dcdcec2c6ab5 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Tue, 7 Apr 2020 16:34:52 +0300
Subject: [PATCH 50/87] evp: add support for Kuznyechik-ctr-acpkm-omac cipher
Add support for AEAD cipher implemented using CTR-ACPKM as block cipher
and CMAC as a MAC value.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/c_all.c | 1 +
src/lib/libcrypto/evp/e_kuznyechik.c | 175 +++++++++++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 1 +
3 files changed, 177 insertions(+)
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index 6a60624d3..ef95d7d68 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -242,6 +242,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_kuznyechik_ofb());
EVP_add_cipher(EVP_kuznyechik_ctr());
EVP_add_cipher(EVP_kuznyechik_ctr_acpkm());
+ EVP_add_cipher(EVP_kuznyechik_ctr_acpkm_omac());
EVP_add_cipher(EVP_kuznyechik_mgm());
#endif
diff --git a/src/lib/libcrypto/evp/e_kuznyechik.c b/src/lib/libcrypto/evp/e_kuznyechik.c
index d022db39c..c6b09173e 100644
--- a/src/lib/libcrypto/evp/e_kuznyechik.c
+++ b/src/lib/libcrypto/evp/e_kuznyechik.c
@@ -25,6 +25,8 @@
#include <openssl/err.h>
#include <openssl/modes.h>
#include <openssl/gost.h>
+#include <openssl/cmac.h>
+#include <openssl/kdftree.h>
#include "evp_locl.h"
#include "modes_lcl.h"
@@ -32,6 +34,14 @@ typedef struct {
KUZNYECHIK_KEY ks;
} EVP_KUZNYECHIK_CTX;
+typedef struct {
+ KUZNYECHIK_KEY ks;
+ CMAC_CTX *cmac;
+ int iv_set;
+ int taglen;
+ unsigned char tag[16];
+} EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX;
+
static int
kuznyechik_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
@@ -178,6 +188,160 @@ kuznyechik_ctr_acpkm_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
return gost3412_ctr_acpkm_get_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx));
}
+static int
+kuznyechik_ctr_acpkm_omac_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX *c = ctx->cipher_data;
+ unsigned char out[64];
+
+ c->taglen = -1;
+ if (iv) {
+ unsigned int il = EVP_CIPHER_CTX_iv_length(ctx) - 8;
+ memcpy(ctx->iv, iv, il);
+ memset(ctx->iv + il, 0, EVP_MAX_IV_LENGTH - il);
+ memcpy(ctx->oiv, iv + il, 8);
+ c->iv_set = 1;
+ ctx->num = 0;
+ }
+
+ if (!key)
+ return 1;
+
+ if (!c->iv_set)
+ return 0;
+
+ if (!KDF_TREE(EVP_streebog256(), NULL,
+ key, EVP_CIPHER_CTX_key_length(ctx),
+ "kdf tree", 8,
+ ctx->oiv, 8,
+ 1,
+ out, sizeof(out)))
+ return 0;
+
+ Kuznyechik_set_key(&c->ks, out, 1);
+
+ return CMAC_Init(c->cmac, out + 32, 32, EVP_kuznyechik_cbc(), NULL);
+}
+
+static int
+kuznyechik_ctr_acpkm_omac_cleanup(EVP_CIPHER_CTX *ctx)
+{
+ EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX *c = ctx->cipher_data;
+
+ CMAC_CTX_free(c->cmac);
+
+ return 1;
+}
+
+static int
+kuznyechik_ctr_acpkm_omac_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+ EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX, ctx);
+
+ switch (type) {
+ case EVP_CTRL_GOST_SET_MESHING:
+ key->ks.key_meshing = arg;
+ return 1;
+ case EVP_CTRL_INIT:
+ /* deafult for tests */
+ key->ks.key_meshing = 32;
+ key->iv_set = 0;
+ key->cmac = CMAC_CTX_new();
+ return 1;
+ case EVP_CTRL_GCM_SET_TAG:
+ if (arg <= 0 || arg > sizeof(key->tag) || ctx->encrypt)
+ return 0;
+
+ memcpy(key->tag, ptr, arg);
+ key->taglen = arg;
+ return 1;
+ case EVP_CTRL_GCM_GET_TAG:
+ if (arg <= 0 || arg > sizeof(key->tag) || !ctx->encrypt || key->taglen < 0)
+ return 0;
+ memcpy(ptr, key->tag, arg);
+ return 1;
+ default:
+ return kuznyechik_ctl(ctx, type, arg, ptr);
+ }
+}
+
+static int
+kuznyechik_ctr_acpkm_omac_final(EVP_CIPHER_CTX *ctx)
+{
+ EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX, ctx);
+ unsigned char tmp[EVP_MAX_BLOCK_LENGTH];
+ size_t taglen = sizeof(tmp);
+
+ /* Do not reuse IV */
+ key->iv_set = 0;
+
+ CMAC_Final(key->cmac, tmp, &taglen);
+ if (ctx->encrypt) {
+ CRYPTO_ctr128_encrypt(tmp, key->tag, taglen, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block128_f)Kuznyechik_acpkm_encrypt);
+ key->taglen = taglen;
+ } else {
+ CRYPTO_ctr128_encrypt(tmp, tmp, taglen, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block128_f)Kuznyechik_acpkm_encrypt);
+ if (key->taglen <= 0 ||
+ key->taglen > taglen ||
+ timingsafe_memcmp(tmp, key->tag, key->taglen))
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+kuznyechik_ctr_acpkm_omac_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+ size_t len)
+{
+ EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX, ctx);
+
+ if (ctx->encrypt)
+ CMAC_Update(key->cmac, in, len);
+
+ CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block128_f)Kuznyechik_acpkm_encrypt);
+ if (!ctx->encrypt)
+ CMAC_Update(key->cmac, out, len);
+
+ if (!in)
+ return kuznyechik_ctr_acpkm_omac_final(ctx);
+
+ return len;
+}
+
+static int
+kuznyechik_ctr_acpkm_omac_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* Also set meshing section size here.
+ * There is no other good place to enable meshing for CMS
+ */
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 256 * 1024, 0);
+
+ return gost3412_ctr_acpkm_set_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx) - 8);
+}
+
+static int
+kuznyechik_ctr_acpkm_omac_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ int ret;
+ EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX, ctx);
+
+ /* Also set meshing section size here.
+ * There is no other good place to enable meshing for CMS
+ */
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 256 * 1024, 0);
+
+ ret = gost3412_ctr_acpkm_get_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx) - 8);
+ if (ret > 0)
+ key->iv_set = 1;
+
+ return ret;
+}
+
IMPLEMENT_BLOCK_CIPHER(kuznyechik, ks, Kuznyechik, EVP_KUZNYECHIK_CTX,
NID_kuznyechik, 16, 32, 16, 128, 0, kuznyechik_init_key, NULL,
EVP_CIPHER_set_asn1_iv,
@@ -200,6 +364,17 @@ BLOCK_CIPHER_def1(kuznyechik, ctr_acpkm, ctr_acpkm, CTR, EVP_KUZNYECHIK_CTX,
kuznyechik_ctr_acpkm_get_asn1_params,
kuznyechik_acpkm_ctl)
+#define NID_kuznyechik_ctr_acpkm_omac NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac
+
+BLOCK_CIPHER_def1(kuznyechik, ctr_acpkm_omac, ctr_acpkm_omac, CTR, EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX,
+ NID_kuznyechik, 1, 32, 16,
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CTRL_INIT | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV |EVP_CIPH_FLAG_CUSTOM_CIPHER,
+ kuznyechik_ctr_acpkm_omac_init_key,
+ kuznyechik_ctr_acpkm_omac_cleanup,
+ kuznyechik_ctr_acpkm_omac_set_asn1_params,
+ kuznyechik_ctr_acpkm_omac_get_asn1_params,
+ kuznyechik_ctr_acpkm_omac_ctl)
+
#define EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN 16
typedef struct {
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 50b157525..9c618ddd5 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -863,6 +863,7 @@ const EVP_CIPHER *EVP_kuznyechik_cfb128(void);
const EVP_CIPHER *EVP_kuznyechik_ofb(void);
const EVP_CIPHER *EVP_kuznyechik_ctr(void);
const EVP_CIPHER *EVP_kuznyechik_ctr_acpkm(void);
+const EVP_CIPHER *EVP_kuznyechik_ctr_acpkm_omac(void);
const EVP_CIPHER *EVP_kuznyechik_mgm(void);
#endif
--
2.17.1

View file

@ -0,0 +1,251 @@
From c797b2060c4a6bb2d7d9c3c9cb6aa6d4b6ed94c7 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Tue, 7 Apr 2020 16:34:52 +0300
Subject: [PATCH 51/87] evp: add support for Magma-ctr-acpkm-omac cipher
Add support for AEAD cipher implemented using CTR-ACPKM as block cipher
and CMAC as a MAC value.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/c_all.c | 1 +
src/lib/libcrypto/evp/e_magma.c | 175 ++++++++++++++++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 1 +
3 files changed, 177 insertions(+)
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index ef95d7d68..90d0f7e20 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -235,6 +235,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_magma_ofb());
EVP_add_cipher(EVP_magma_ctr());
EVP_add_cipher(EVP_magma_ctr_acpkm());
+ EVP_add_cipher(EVP_magma_ctr_acpkm_omac());
EVP_add_cipher(EVP_magma_mgm());
EVP_add_cipher(EVP_kuznyechik_ecb());
EVP_add_cipher(EVP_kuznyechik_cbc());
diff --git a/src/lib/libcrypto/evp/e_magma.c b/src/lib/libcrypto/evp/e_magma.c
index ae78824eb..ffaeda505 100644
--- a/src/lib/libcrypto/evp/e_magma.c
+++ b/src/lib/libcrypto/evp/e_magma.c
@@ -25,6 +25,8 @@
#include <openssl/err.h>
#include <openssl/modes.h>
#include <openssl/gost.h>
+#include <openssl/cmac.h>
+#include <openssl/kdftree.h>
#include "evp_locl.h"
#include "modes_lcl.h"
@@ -32,6 +34,14 @@ typedef struct {
MAGMA_KEY ks;
} EVP_MAGMA_CTX;
+typedef struct {
+ MAGMA_KEY ks;
+ CMAC_CTX *cmac;
+ int iv_set;
+ int taglen;
+ unsigned char tag[8];
+} EVP_MAGMA_CTR_ACPKM_OMAC_CTX;
+
static int
magma_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
@@ -172,6 +182,160 @@ magma_ctr_acpkm_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
return gost3412_ctr_acpkm_get_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx));
}
+static int
+magma_ctr_acpkm_omac_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_MAGMA_CTR_ACPKM_OMAC_CTX *c = ctx->cipher_data;
+ unsigned char out[64];
+
+ c->taglen = -1;
+ if (iv) {
+ unsigned int il = EVP_CIPHER_CTX_iv_length(ctx) - 8;
+ memcpy(ctx->iv, iv, il);
+ memset(ctx->iv + il, 0, EVP_MAX_IV_LENGTH - il);
+ memcpy(ctx->oiv, iv + il, 8);
+ c->iv_set = 1;
+ ctx->num = 0;
+ }
+
+ if (!key)
+ return 1;
+
+ if (!c->iv_set)
+ return 0;
+
+ if (!KDF_TREE(EVP_streebog256(), NULL,
+ key, EVP_CIPHER_CTX_key_length(ctx),
+ "kdf tree", 8,
+ ctx->oiv, 8,
+ 1,
+ out, sizeof(out)))
+ return 0;
+
+ Magma_set_key(&c->ks, out);
+
+ return CMAC_Init(c->cmac, out + 32, 32, EVP_magma_cbc(), NULL);
+}
+
+static int
+magma_ctr_acpkm_omac_cleanup(EVP_CIPHER_CTX *ctx)
+{
+ EVP_MAGMA_CTR_ACPKM_OMAC_CTX *c = ctx->cipher_data;
+
+ CMAC_CTX_free(c->cmac);
+
+ return 1;
+}
+
+static int
+magma_ctr_acpkm_omac_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+ EVP_MAGMA_CTR_ACPKM_OMAC_CTX *key = EVP_C_DATA(EVP_MAGMA_CTR_ACPKM_OMAC_CTX, ctx);
+
+ switch (type) {
+ case EVP_CTRL_GOST_SET_MESHING:
+ key->ks.key_meshing = arg;
+ return 1;
+ case EVP_CTRL_INIT:
+ /* deafult for tests */
+ key->ks.key_meshing = 16;
+ key->iv_set = 0;
+ key->cmac = CMAC_CTX_new();
+ return 1;
+ case EVP_CTRL_GCM_SET_TAG:
+ if (arg <= 0 || arg > sizeof(key->tag) || ctx->encrypt)
+ return 0;
+
+ memcpy(key->tag, ptr, arg);
+ key->taglen = arg;
+ return 1;
+ case EVP_CTRL_GCM_GET_TAG:
+ if (arg <= 0 || arg > sizeof(key->tag) || !ctx->encrypt || key->taglen < 0)
+ return 0;
+ memcpy(ptr, key->tag, arg);
+ return 1;
+ default:
+ return magma_ctl(ctx, type, arg, ptr);
+ }
+}
+
+static int
+magma_ctr_acpkm_omac_final(EVP_CIPHER_CTX *ctx)
+{
+ EVP_MAGMA_CTR_ACPKM_OMAC_CTX *key = EVP_C_DATA(EVP_MAGMA_CTR_ACPKM_OMAC_CTX, ctx);
+ unsigned char tmp[EVP_MAX_BLOCK_LENGTH];
+ size_t taglen = sizeof(tmp);
+
+ /* Do not reuse IV */
+ key->iv_set = 0;
+
+ CMAC_Final(key->cmac, tmp, &taglen);
+ if (ctx->encrypt) {
+ CRYPTO_ctr64_encrypt(tmp, key->tag, taglen, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_acpkm_encrypt);
+ key->taglen = taglen;
+ } else {
+ CRYPTO_ctr64_encrypt(tmp, tmp, taglen, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_acpkm_encrypt);
+ if (key->taglen <= 0 ||
+ key->taglen > taglen ||
+ timingsafe_memcmp(tmp, key->tag, key->taglen))
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+magma_ctr_acpkm_omac_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+ size_t len)
+{
+ EVP_MAGMA_CTR_ACPKM_OMAC_CTX *key = EVP_C_DATA(EVP_MAGMA_CTR_ACPKM_OMAC_CTX, ctx);
+
+ if (ctx->encrypt)
+ CMAC_Update(key->cmac, in, len);
+
+ CRYPTO_ctr64_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_acpkm_encrypt);
+ if (!ctx->encrypt)
+ CMAC_Update(key->cmac, out, len);
+
+ if (!in)
+ return magma_ctr_acpkm_omac_final(ctx);
+
+ return len;
+}
+
+static int
+magma_ctr_acpkm_omac_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* Also set meshing section size here.
+ * There is no other good place to enable meshing for CMS
+ */
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 8 * 1024, 0);
+
+ return gost3412_ctr_acpkm_set_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx) - 8);
+}
+
+static int
+magma_ctr_acpkm_omac_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ int ret;
+ EVP_MAGMA_CTR_ACPKM_OMAC_CTX *key = EVP_C_DATA(EVP_MAGMA_CTR_ACPKM_OMAC_CTX, ctx);
+
+ /* Also set meshing section size here.
+ * There is no other good place to enable meshing for CMS
+ */
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 8 * 1024, 0);
+
+ ret = gost3412_ctr_acpkm_get_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx) - 8);
+ if (ret > 0)
+ key->iv_set = 1;
+
+ return ret;
+}
+
IMPLEMENT_BLOCK_CIPHER(magma, ks, Magma, EVP_MAGMA_CTX,
NID_magma, 8, 32, 8, 64, 0, magma_init_key, NULL,
EVP_CIPHER_set_asn1_iv,
@@ -194,6 +358,17 @@ BLOCK_CIPHER_def1(magma, ctr_acpkm, ctr_acpkm, CTR, EVP_MAGMA_CTX,
magma_ctr_acpkm_get_asn1_params,
magma_acpkm_ctl)
+#define NID_magma_ctr_acpkm_omac NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac
+
+BLOCK_CIPHER_def1(magma, ctr_acpkm_omac, ctr_acpkm_omac, CTR, EVP_MAGMA_CTR_ACPKM_OMAC_CTX,
+ NID_magma, 1, 32, 12,
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CTRL_INIT | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV |EVP_CIPH_FLAG_CUSTOM_CIPHER,
+ magma_ctr_acpkm_omac_init_key,
+ magma_ctr_acpkm_omac_cleanup,
+ magma_ctr_acpkm_omac_set_asn1_params,
+ magma_ctr_acpkm_omac_get_asn1_params,
+ magma_ctr_acpkm_omac_ctl)
+
#define EVP_AEAD_MAGMA_MGM_TAG_LEN 16
typedef struct {
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 9c618ddd5..981351d76 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -856,6 +856,7 @@ const EVP_CIPHER *EVP_magma_cfb64(void);
const EVP_CIPHER *EVP_magma_ofb(void);
const EVP_CIPHER *EVP_magma_ctr(void);
const EVP_CIPHER *EVP_magma_ctr_acpkm(void);
+const EVP_CIPHER *EVP_magma_ctr_acpkm_omac(void);
const EVP_CIPHER *EVP_magma_mgm(void);
const EVP_CIPHER *EVP_kuznyechik_ecb(void);
const EVP_CIPHER *EVP_kuznyechik_cbc(void);
--
2.17.1

View file

@ -1,19 +1,19 @@
From 6baa93be806961444d000337366b8ede5deb1c8d Mon Sep 17 00:00:00 2001 From fbd3052d4bda0a41383a04ac78e9bd0147655130 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com> From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 19 Mar 2020 18:13:42 +0300 Date: Thu, 19 Mar 2020 18:13:42 +0300
Subject: [PATCH] gost: restore CMS support Subject: [PATCH 52/87] gost: restore CMS support
Restore CMS support dropped few years ago when CMS support was removed Restore CMS support dropped few years ago when CMS support was removed
from LibreSSL. from LibreSSL.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
--- ---
src/lib/libcrypto/gost/gostr341001_ameth.c | 14 ++++++++++++++ src/lib/libcrypto/gost/gostr341001_ameth.c | 15 ++++++++++++++-
src/lib/libcrypto/gost/gostr341001_pmeth.c | 5 +++++ src/lib/libcrypto/gost/gostr341001_pmeth.c | 5 +++++
2 files changed, 19 insertions(+) 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c b/src/lib/libcrypto/gost/gostr341001_ameth.c diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 6886859fa..087042f0a 100644 index 880c17cea..2efb001fc 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c --- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c +++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -59,6 +59,9 @@ @@ -59,6 +59,9 @@
@ -26,29 +26,34 @@ index 6886859fa..087042f0a 100644
#include <openssl/gost.h> #include <openssl/gost.h>
@@ -749,6 +752,17 @@ pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2) @@ -776,11 +779,21 @@ pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); int digest = GOST_KEY_get_digest(pkey->pkey.gost);
break;
switch (op) {
+#ifndef OPENSSL_NO_CMS +#ifndef OPENSSL_NO_CMS
+ case ASN1_PKEY_CTRL_CMS_SIGN: + case ASN1_PKEY_CTRL_CMS_SIGN:
+ if (arg1 == 0) + if (arg1 == 0)
+ CMS_SignerInfo_get0_algs(arg2, NULL, NULL, + CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
+ &alg1, &alg2); + &alg1, &alg2);
+ return 1; + break;
+ case ASN1_PKEY_CTRL_CMS_ENVELOPE: + case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+ if (arg1 == 0) + if (arg1 == 0)
+ CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg3); + CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg3);
+ break; + break;
+#endif +#endif
case ASN1_PKEY_CTRL_PKCS7_SIGN:
if (arg1 == 0)
PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
break;
-
case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
if (arg1 == 0) if (arg1 == 0)
PKCS7_RECIP_INFO_get0_alg(arg2, &alg3); PKCS7_RECIP_INFO_get0_alg(arg2, &alg3);
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c
index 0e0cae99e..cacbf3de9 100644 index 455337232..ce4658b13 100644
--- a/src/lib/libcrypto/gost/gostr341001_pmeth.c --- a/src/lib/libcrypto/gost/gostr341001_pmeth.c
+++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c +++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c
@@ -587,6 +587,11 @@ pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) @@ -831,6 +831,11 @@ pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT:
case EVP_PKEY_CTRL_PKCS7_SIGN: case EVP_PKEY_CTRL_PKCS7_SIGN:
case EVP_PKEY_CTRL_DIGESTINIT: case EVP_PKEY_CTRL_DIGESTINIT:
@ -61,5 +66,5 @@ index 0e0cae99e..cacbf3de9 100644
case EVP_PKEY_CTRL_GOST_PARAMSET: case EVP_PKEY_CTRL_GOST_PARAMSET:
-- --
2.20.1 2.17.1

View file

@ -0,0 +1,349 @@
From 39697551e90ec5c96552de4d4666ec00b579dcce Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sun, 5 Apr 2020 22:58:24 +0300
Subject: [PATCH 53/87] gost: add support for CMS and SMIME enveloped files
Add support for CMS and SMIME files using GOST R 34.10-2012 keys and
GOST R 34.12-2015 (Magma and Kuznyechik) algorithms.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/cms/cms_env.c | 2 +-
src/lib/libcrypto/gost/gost_locl.h | 2 +
src/lib/libcrypto/gost/gostr341001_ameth.c | 154 +++++++++++++++++++--
src/lib/libcrypto/gost/gostr341001_pmeth.c | 13 ++
src/lib/libcrypto/objects/obj_mac.num | 4 +
src/lib/libcrypto/objects/objects.txt | 6 +
src/lib/libcrypto/pkcs7/pk7_doit.c | 6 +-
7 files changed, 168 insertions(+), 19 deletions(-)
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
index 74d957eee..911f7a8a2 100644
--- a/src/lib/libcrypto/cms/cms_env.c
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -386,7 +386,7 @@ cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
}
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
- EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) {
+ EVP_PKEY_CTRL_CMS_ENCRYPT, EVP_CIPHER_type(ec->cipher), ri) <= 0) {
CMSerror(CMS_R_CTRL_ERROR);
goto err;
}
diff --git a/src/lib/libcrypto/gost/gost_locl.h b/src/lib/libcrypto/gost/gost_locl.h
index 13e9fd459..1cdc18db9 100644
--- a/src/lib/libcrypto/gost/gost_locl.h
+++ b/src/lib/libcrypto/gost/gost_locl.h
@@ -123,6 +123,8 @@ extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn);
extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len);
extern int gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm,
unsigned int ukm_len, int ukm_be, int out_nid, unsigned char *key);
+extern int gost01_smime_encrypt(EVP_PKEY_CTX *ctx, X509_ALGOR *alg, int nid);
+extern int gost01_smime_decrypt(EVP_PKEY_CTX *pctx, X509_ALGOR *alg);
/* GOST R 34.10 parameters */
extern int GostR3410_get_md_digest(int nid);
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 2efb001fc..965b36237 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -193,6 +193,41 @@ err:
return params;
}
+static ASN1_STRING *
+encode_gost01_kexp_params(EVP_PKEY *pkey)
+{
+ int digest = GOST_KEY_get_digest(pkey->pkey.gost);
+ ASN1_STRING *params = ASN1_STRING_new();
+ X509_ALGOR p;
+
+ if (params == NULL) {
+ GOSTerror(ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ switch (digest) {
+ case NID_id_tc26_gost3411_2012_256:
+ p.algorithm = OBJ_nid2obj(NID_id_tc26_agreement_gost_3410_12_256);
+ break;
+ case NID_id_tc26_gost3411_2012_512:
+ p.algorithm = OBJ_nid2obj(NID_id_tc26_agreement_gost_3410_12_512);
+ break;
+ default:
+ GOSTerror(ERR_R_INTERNAL_ERROR);
+ break;
+ }
+ p.parameter = NULL;
+
+ params->length = i2d_X509_ALGOR(&p, &params->data);
+ params->type = V_ASN1_SEQUENCE;
+
+ return params;
+err:
+ ASN1_STRING_free(params);
+ params = NULL;
+ return NULL;
+}
+
static int
pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
{
@@ -772,10 +807,110 @@ param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
return 1;
}
+int gost01_smime_decrypt(EVP_PKEY_CTX *pctx, X509_ALGOR *alg)
+{
+ int nid = OBJ_obj2nid(alg->algorithm);
+ int format;
+
+ switch (nid) {
+ case NID_id_GostR3410_2001:
+ /* Nothing to do */
+ return 1;
+ case NID_id_tc26_wrap_gostr3412_2015_magma_kexp15:
+ format = GOST_ENC_FORMAT_PSKEY_MAGMA;
+ break;
+ case NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15:
+ format = GOST_ENC_FORMAT_PSKEY_KUZNYECHIK;
+ break;
+ default:
+ GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
+ return 0;
+ }
+ if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+ EVP_PKEY_CTRL_GOST_ENC_FORMAT,
+ format, NULL) <= 0) {
+ GOSTerror(ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
+int gost01_smime_encrypt(EVP_PKEY_CTX *ctx, X509_ALGOR *alg, int enc_nid)
+{
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+ int digest, nid, format;
+ ASN1_STRING *params;
+
+ switch (enc_nid) {
+ case NID_id_Gost28147_89:
+ format = GOST_ENC_FORMAT_4490;
+ nid = NID_id_GostR3410_2001;
+ break;
+ case NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm:
+ case NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac:
+ format = GOST_ENC_FORMAT_PSKEY_MAGMA;
+ nid = NID_id_tc26_wrap_gostr3412_2015_magma_kexp15;
+ break;
+ case NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm:
+ case NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac:
+ format = GOST_ENC_FORMAT_PSKEY_KUZNYECHIK;
+ nid = NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15;
+ break;
+ default:
+ return 0;
+ }
+
+ if (EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_ENCRYPT,
+ EVP_PKEY_CTRL_GOST_ENC_FORMAT, format,
+ NULL) != 1)
+ return 0;
+
+ if (EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_ENCRYPT,
+ EVP_PKEY_CTRL_GOST_GET_DIGEST, 0,
+ &digest) != 1)
+ return 0;
+
+ switch (digest) {
+ case NID_id_GostR3411_94_CryptoProParamSet:
+ if ((params = encode_gost01_algor_params(pkey)) == NULL)
+ return -1;
+ break;
+
+ case NID_id_tc26_gost3411_2012_256:
+ case NID_id_tc26_gost3411_2012_512:
+ if ((params = encode_gost01_kexp_params(pkey)) == NULL)
+ return -1;
+ break;
+
+ default:
+ return 0;
+ }
+ return X509_ALGOR_set0(alg, OBJ_nid2obj(nid), V_ASN1_SEQUENCE, params);
+}
+
+#ifndef OPENSSL_NO_CMS
+static int
+gost01_cms_decrypt(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pkctx;
+ X509_ALGOR *cmsalg;
+
+ pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (pkctx == NULL)
+ return 0;
+
+ if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
+ return 0;
+
+ return gost01_smime_decrypt(pkctx, cmsalg);
+}
+#endif
+
static int
pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
- X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL;
+ X509_ALGOR *alg1 = NULL, *alg2 = NULL;
int digest = GOST_KEY_get_digest(pkey->pkey.gost);
switch (op) {
@@ -786,8 +921,8 @@ pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
&alg1, &alg2);
break;
case ASN1_PKEY_CTRL_CMS_ENVELOPE:
- if (arg1 == 0)
- CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg3);
+ if (arg1 == 1)
+ return gost01_cms_decrypt(arg2);
break;
#endif
case ASN1_PKEY_CTRL_PKCS7_SIGN:
@@ -795,9 +930,7 @@ pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
break;
case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
- if (arg1 == 0)
- PKCS7_RECIP_INFO_get0_alg(arg2, &alg3);
- break;
+ return 1;
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
*(int *)arg2 = GostR3410_get_md_digest(digest);
return 2;
@@ -810,15 +943,6 @@ pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
X509_ALGOR_set0(alg1, OBJ_nid2obj(GostR3410_get_md_digest(digest)), V_ASN1_NULL, 0);
if (alg2)
X509_ALGOR_set0(alg2, OBJ_nid2obj(GostR3410_get_pk_digest(digest)), V_ASN1_NULL, 0);
- if (alg3) {
- ASN1_STRING *params = encode_gost01_algor_params(pkey);
- if (params == NULL) {
- return -1;
- }
- X509_ALGOR_set0(alg3,
- OBJ_nid2obj(GostR3410_get_pk_digest(digest)),
- V_ASN1_SEQUENCE, params);
- }
return 1;
}
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c
index ce4658b13..07ca4d3a3 100644
--- a/src/lib/libcrypto/gost/gostr341001_pmeth.c
+++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c
@@ -61,6 +61,9 @@
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/x509.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
#include "evp_locl.h"
#include "gost_locl.h"
@@ -817,6 +820,7 @@ static int
pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx);
+ X509_ALGOR *alg;
switch (type) {
case EVP_PKEY_CTRL_MD:
@@ -828,11 +832,20 @@ pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
pctx->md = p2;
return 1;
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+ PKCS7_RECIP_INFO_get0_alg(p2, &alg);
+ return gost01_smime_encrypt(ctx, alg, p1);
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+ PKCS7_RECIP_INFO_get0_alg(p2, &alg);
+ return gost01_smime_decrypt(ctx, alg);
case EVP_PKEY_CTRL_PKCS7_SIGN:
case EVP_PKEY_CTRL_DIGESTINIT:
+ return 1;
+
#ifndef OPENSSL_NO_CMS
case EVP_PKEY_CTRL_CMS_ENCRYPT:
+ if (CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg) <= 0)
+ return 0;
+ return gost01_smime_encrypt(ctx, alg, p1);
case EVP_PKEY_CTRL_CMS_DECRYPT:
case EVP_PKEY_CTRL_CMS_SIGN:
#endif
diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num
index 2c0d3356f..188349d71 100644
--- a/src/lib/libcrypto/objects/obj_mac.num
+++ b/src/lib/libcrypto/objects/obj_mac.num
@@ -1016,3 +1016,7 @@ id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm 1015
id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac 1016
id_tc26_cipher_gostr3412_2015_kuznyechik_mgm 1017
kuznyechik_mac 1018
+id_tc26_agreement_gost_3410_12_256 1019
+id_tc26_agreement_gost_3410_12_512 1020
+id_tc26_wrap_gostr3412_2015_magma_kexp15 1021
+id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1022
diff --git a/src/lib/libcrypto/objects/objects.txt b/src/lib/libcrypto/objects/objects.txt
index 4bf75f700..0d2af66ac 100644
--- a/src/lib/libcrypto/objects/objects.txt
+++ b/src/lib/libcrypto/objects/objects.txt
@@ -1416,6 +1416,12 @@ tc26 1 5 2 2 : kuznyechik-ctr-acpkm-omac
tc26 1 5 2 3 : kuznyechik-mgm
: kuznyechik-mac
+tc26 1 6 1 : id-tc26-agreement-gost-3410-12-256
+tc26 1 6 2 : id-tc26-agreement-gost-3410-12-512
+
+tc26 1 7 1 1 : id-tc26-wrap-gostr3412-2015-magma-kexp15
+tc26 1 7 2 1 : id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15
+
# Curves from draft-ietf-curdle-pkix-02
1 3 101 110 : X25519
1 3 101 111 : X448
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c
index 81a72f681..10cbd348e 100644
--- a/src/lib/libcrypto/pkcs7/pk7_doit.c
+++ b/src/lib/libcrypto/pkcs7/pk7_doit.c
@@ -138,7 +138,7 @@ err:
}
static int
-pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *key, int keylen)
+pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *key, int keylen, int enc_type)
{
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey = NULL;
@@ -158,7 +158,7 @@ pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *key, int keylen)
goto err;
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
- EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) {
+ EVP_PKEY_CTRL_PKCS7_ENCRYPT, enc_type, ri) <= 0) {
PKCS7error(PKCS7_R_CTRL_ERROR);
goto err;
}
@@ -362,7 +362,7 @@ PKCS7_dataInit(PKCS7 *p7, BIO *bio)
/* Lets do the pub key stuff :-) */
for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
- if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
+ if (pkcs7_encode_rinfo(ri, key, keylen, EVP_CIPHER_type(evp_cipher)) <= 0)
goto err;
}
explicit_bzero(key, keylen);
--
2.17.1

View file

@ -0,0 +1,224 @@
From c07aac0a0dced669f5291aad98c453f3d47eab10 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Tue, 7 Apr 2020 16:36:32 +0300
Subject: [PATCH 54/87] cms: add support for using AEAD ciphers in CMS files
Russian standards body has added definition for special unprotected
attribute (id-cms-mac-attr) used together with AEAD ciphers (primarily
CTR-ACKM-OMAC) to store MAC value together with encrypted data.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/cms/cms_enc.c | 66 ++++++++++++++++++++++++++-
src/lib/libcrypto/cms/cms_env.c | 15 +++++-
src/lib/libcrypto/cms/cms_lcl.h | 7 ++-
src/lib/libcrypto/cms/cms_lib.c | 8 +++-
src/lib/libcrypto/objects/obj_mac.num | 1 +
src/lib/libcrypto/objects/objects.txt | 1 +
6 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/src/lib/libcrypto/cms/cms_enc.c b/src/lib/libcrypto/cms/cms_enc.c
index fd2df99c6..2b8f9c5b8 100644
--- a/src/lib/libcrypto/cms/cms_enc.c
+++ b/src/lib/libcrypto/cms/cms_enc.c
@@ -68,7 +68,8 @@
/* Return BIO based on EncryptedContentInfo and key */
BIO *
-cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
+cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
+ STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs)
{
BIO *b;
EVP_CIPHER_CTX *ctx;
@@ -189,6 +190,23 @@ cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
ASN1_TYPE_free(calg->parameter);
calg->parameter = NULL;
}
+ } else if (ciph->flags & EVP_CIPH_FLAG_AEAD_CIPHER) {
+ int idx = X509at_get_attr_by_NID(unprotectedAttrs, NID_id_cms_mac_attr, -1);
+ X509_ATTRIBUTE *attr;
+ ASN1_TYPE *type;
+
+ if (idx == -1 ||
+ (attr = X509at_get_attr(unprotectedAttrs, idx)) == NULL ||
+ attr->single != 0 ||
+ sk_ASN1_TYPE_num(attr->value.set) != 1 ||
+ (type = sk_ASN1_TYPE_value(attr->value.set, 0)) == NULL ||
+ type->type != V_ASN1_OCTET_STRING ||
+ !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG,
+ type->value.octet_string->length,
+ type->value.octet_string->data)) {
+ CMSerror(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+ goto err;
+ }
}
ok = 1;
@@ -204,6 +222,43 @@ cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
return NULL;
}
+int cms_EncryptedContent_final(CMS_EncryptedContentInfo *ec,
+ BIO *chain, STACK_OF(X509_ATTRIBUTE) **unprotectedAttrs)
+{
+ EVP_CIPHER_CTX *ctx = NULL;
+ BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER);
+
+ if (mbio == NULL) {
+ CMSerror(CMS_R_CONTENT_NOT_FOUND);
+ return 0;
+ }
+
+ BIO_get_cipher_ctx(mbio, &ctx);
+ if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) {
+ unsigned char tag[EVP_MAX_MD_SIZE];
+ int taglen;
+ int nid = EVP_CIPHER_CTX_nid(ctx);
+
+ /* Most of the AEAD ciphers have 16-bit tags except Magma ciphers */
+ if (nid == NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac ||
+ nid == NID_id_tc26_cipher_gostr3412_2015_magma_mgm)
+ taglen = 8;
+ else
+ taglen = 16;
+
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG,
+ taglen, tag) <= 0) {
+ CMSerror(CMS_R_CTRL_FAILURE);
+ return 0;
+ }
+
+ if (!X509at_add1_attr_by_NID(unprotectedAttrs, NID_id_cms_mac_attr, V_ASN1_OCTET_STRING, tag, taglen))
+ return 0;
+ }
+
+ return 1;
+}
+
int
cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen)
@@ -258,5 +313,12 @@ cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
enc->version = 2;
- return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
+ return cms_EncryptedContent_init_bio(enc->encryptedContentInfo, enc->unprotectedAttrs);
+}
+
+int cms_EncryptedData_final(CMS_ContentInfo *cms, BIO *chain)
+{
+ CMS_EncryptedData *enc = cms->d.encryptedData;
+
+ return cms_EncryptedContent_final(enc->encryptedContentInfo, chain, &enc->unprotectedAttrs);
}
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
index 911f7a8a2..f5e9280d4 100644
--- a/src/lib/libcrypto/cms/cms_env.c
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -927,7 +927,7 @@ cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
/* Get BIO first to set up key */
ec = cms->d.envelopedData->encryptedContentInfo;
- ret = cms_EncryptedContent_init_bio(ec);
+ ret = cms_EncryptedContent_init_bio(ec, cms->d.envelopedData->unprotectedAttrs);
/* If error or no cipher end of processing */
@@ -960,6 +960,19 @@ cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
return NULL;
}
+int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain)
+{
+ CMS_EnvelopedData *env = NULL;
+
+ env = cms_get0_enveloped(cms);
+ if (env == NULL) {
+ CMSerror(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
+ return 0;
+ }
+
+ return cms_EncryptedContent_final(env->encryptedContentInfo, chain, &env->unprotectedAttrs);
+}
+
/*
* Get RecipientInfo type (if any) supported by a key (public or private). To
* retain compatibility with previous behaviour if the ctrl value isn't
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h
index 8083e5537..fdfd12160 100644
--- a/src/lib/libcrypto/cms/cms_lcl.h
+++ b/src/lib/libcrypto/cms/cms_lcl.h
@@ -442,16 +442,21 @@ int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert);
int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert);
int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert);
-BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec,
+ STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs);
BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
+int cms_EncryptedData_final(CMS_ContentInfo *cms, BIO *chain);
int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen);
+int cms_EncryptedContent_final(CMS_EncryptedContentInfo *ec,
+ BIO *chain, STACK_OF(X509_ATTRIBUTE) **unprotectedAttrs);
int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
+int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain);
CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
int cms_pkey_get_ri_type(EVP_PKEY *pk);
diff --git a/src/lib/libcrypto/cms/cms_lib.c b/src/lib/libcrypto/cms/cms_lib.c
index b6580dd6f..787a8f99e 100644
--- a/src/lib/libcrypto/cms/cms_lib.c
+++ b/src/lib/libcrypto/cms/cms_lib.c
@@ -215,12 +215,16 @@ CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
switch (OBJ_obj2nid(cms->contentType)) {
case NID_pkcs7_data:
- case NID_pkcs7_enveloped:
- case NID_pkcs7_encrypted:
case NID_id_smime_ct_compressedData:
/* Nothing to do */
return 1;
+ case NID_pkcs7_enveloped:
+ return cms_EnvelopedData_final(cms, cmsbio);
+
+ case NID_pkcs7_encrypted:
+ return cms_EncryptedData_final(cms, cmsbio);
+
case NID_pkcs7_signed:
return cms_SignedData_final(cms, cmsbio);
diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num
index 188349d71..6e494cb92 100644
--- a/src/lib/libcrypto/objects/obj_mac.num
+++ b/src/lib/libcrypto/objects/obj_mac.num
@@ -1020,3 +1020,4 @@ id_tc26_agreement_gost_3410_12_256 1019
id_tc26_agreement_gost_3410_12_512 1020
id_tc26_wrap_gostr3412_2015_magma_kexp15 1021
id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1022
+id_cms_mac_attr 1023
diff --git a/src/lib/libcrypto/objects/objects.txt b/src/lib/libcrypto/objects/objects.txt
index 0d2af66ac..3f810dcf8 100644
--- a/src/lib/libcrypto/objects/objects.txt
+++ b/src/lib/libcrypto/objects/objects.txt
@@ -1368,6 +1368,7 @@ brainpool 1 14 : brainpoolP512t1
: gost89-cbc
member-body 643 7 1 : tc26
+tc26 0 6 1 1 : id-cms-mac-attr
!Cname id-tc26-gost3411-2012-256
tc26 1 2 2 : streebog256 : GOST R 34.11-2012 (256 bit)
!Cname id-tc26-gost3411-2012-512
--
2.17.1

View file

@ -0,0 +1,32 @@
From 49093fb8911e3aa0422abbef054ac4a02b8e7fc2 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Mon, 6 Apr 2020 01:35:55 +0300
Subject: [PATCH 55/87] cms: populate SMIMECaps with new GOST algorithms
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/cms/cms_sd.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/lib/libcrypto/cms/cms_sd.c b/src/lib/libcrypto/cms/cms_sd.c
index 95343d088..b652260c3 100644
--- a/src/lib/libcrypto/cms/cms_sd.c
+++ b/src/lib/libcrypto/cms/cms_sd.c
@@ -999,6 +999,12 @@ int
CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
{
if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) ||
+ !cms_add_digest_smcap(smcap, NID_id_tc26_gost3411_2012_256, -1) ||
+ !cms_add_digest_smcap(smcap, NID_id_tc26_gost3411_2012_512, -1) ||
+ !cms_add_digest_smcap(smcap, NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm, -1) ||
+ !cms_add_digest_smcap(smcap, NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm, -1) ||
+ !cms_add_digest_smcap(smcap, NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, -1) ||
+ !cms_add_digest_smcap(smcap, NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac, -1) ||
!cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) ||
!cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) ||
!cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) ||
--
2.17.1

View file

@ -0,0 +1,112 @@
From a93a2217ebca9eb7b6190a142e71bbc2a7a0db97 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 8 Apr 2020 18:00:40 +0300
Subject: [PATCH 56/87] cms: allow keys support different RI types
GOST keys support both KeyTransport and KeyAgreement. Instead of
checking that RI type matches one of EVP_PKEY, check if EVP_PKEY
supports this RI type.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/cms/cms_env.c | 20 ++++++++++++++++++++
src/lib/libcrypto/cms/cms_lcl.h | 1 +
src/lib/libcrypto/cms/cms_smime.c | 14 ++++++--------
src/lib/libcrypto/evp/evp.h | 1 +
4 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
index f5e9280d4..17778a4fe 100644
--- a/src/lib/libcrypto/cms/cms_env.c
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -989,3 +989,23 @@ cms_pkey_get_ri_type(EVP_PKEY *pk)
}
return CMS_RECIPINFO_TRANS;
}
+
+/* Some PKEYs (GOST) support different RecipientInfo types */
+int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type)
+{
+ int supportedRiType;
+
+ if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) {
+ int i, r;
+
+ i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, ri_type, &r);
+ if (i > 0)
+ return r;
+ }
+
+ supportedRiType = cms_pkey_get_ri_type(pk);
+ if (supportedRiType < 0)
+ return 0;
+
+ return (supportedRiType == ri_type);
+}
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h
index fdfd12160..d400f5028 100644
--- a/src/lib/libcrypto/cms/cms_lcl.h
+++ b/src/lib/libcrypto/cms/cms_lcl.h
@@ -460,6 +460,7 @@ int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain);
CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
int cms_pkey_get_ri_type(EVP_PKEY *pk);
+int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type);
/* KARI routines */
int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
EVP_PKEY *pk, unsigned int flags);
diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c
index 367810f40..d02ec5db1 100644
--- a/src/lib/libcrypto/cms/cms_smime.c
+++ b/src/lib/libcrypto/cms/cms_smime.c
@@ -677,21 +677,19 @@ CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
{
STACK_OF(CMS_RecipientInfo) *ris;
CMS_RecipientInfo *ri;
- int i, r, ri_type;
+ int i, r;
int debug = 0, match_ri = 0;
ris = CMS_get0_RecipientInfos(cms);
if (ris)
debug = cms->d.envelopedData->encryptedContentInfo->debug;
- ri_type = cms_pkey_get_ri_type(pk);
- if (ri_type == CMS_RECIPINFO_NONE) {
- CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
- return 0;
- }
for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+ int ri_type;
+
ri = sk_CMS_RecipientInfo_value(ris, i);
- if (CMS_RecipientInfo_type(ri) != ri_type)
+ ri_type = CMS_RecipientInfo_type(ri);
+ if (!cms_pkey_is_ri_type_supported(pk, ri_type))
continue;
match_ri = 1;
if (ri_type == CMS_RECIPINFO_AGREE) {
@@ -734,7 +732,7 @@ CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
}
}
/* If no cert, key transport and not debugging always return success */
- if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) {
+ if (cert == NULL && cms_pkey_get_ri_type(pk) == CMS_RECIPINFO_TRANS && match_ri && !debug) {
ERR_clear_error();
return 1;
}
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 981351d76..48c7e7360 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1036,6 +1036,7 @@ void EVP_PBE_cleanup(void);
#define ASN1_PKEY_CTRL_CMS_SIGN 0x5
#define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7
#define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8
+#define ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED 0x9
int EVP_PKEY_asn1_get_count(void);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
--
2.17.1

View file

@ -0,0 +1,210 @@
From 4d039c645d00d539a40cf52ff3e7e776b8ae792a Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 8 Apr 2020 18:09:14 +0300
Subject: [PATCH 57/87] evp: support kuznyechik kexp15 keywrap algorithm
Add support for kuznyechik kexp15 key wrapping algorithm
(draft-smyshlyaev-tls12-gost-suites, Section 8.2.1).
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/c_all.c | 1 +
src/lib/libcrypto/evp/e_kuznyechik.c | 143 +++++++++++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 1 +
3 files changed, 145 insertions(+)
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index 90d0f7e20..482cc4e06 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -244,6 +244,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_kuznyechik_ctr());
EVP_add_cipher(EVP_kuznyechik_ctr_acpkm());
EVP_add_cipher(EVP_kuznyechik_ctr_acpkm_omac());
+ EVP_add_cipher(EVP_kuznyechik_kexp15_wrap());
EVP_add_cipher(EVP_kuznyechik_mgm());
#endif
diff --git a/src/lib/libcrypto/evp/e_kuznyechik.c b/src/lib/libcrypto/evp/e_kuznyechik.c
index c6b09173e..3c2a70aeb 100644
--- a/src/lib/libcrypto/evp/e_kuznyechik.c
+++ b/src/lib/libcrypto/evp/e_kuznyechik.c
@@ -42,6 +42,13 @@ typedef struct {
unsigned char tag[16];
} EVP_KUZNYECHIK_CTR_ACPKM_OMAC_CTX;
+typedef struct {
+ KUZNYECHIK_KEY ks;
+ CMAC_CTX *cmac;
+ int iv_set;
+ int key_set;
+} EVP_KUZNYECHIK_KEXP15_WRAP_CTX;
+
static int
kuznyechik_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
@@ -342,6 +349,131 @@ kuznyechik_ctr_acpkm_omac_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params
return ret;
}
+#define KEXP15_IV_OFFSET 24
+#define KEXP15_KUZNYECHIK_IV_PART 8
+
+static int
+kuznyechik_kexp15_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_KUZNYECHIK_KEXP15_WRAP_CTX *c = ctx->cipher_data;
+
+ if (iv) {
+ memset(ctx->iv, 0, sizeof(ctx->iv));
+ memcpy(ctx->iv, iv + KEXP15_IV_OFFSET, KEXP15_KUZNYECHIK_IV_PART);
+ c->iv_set = 1;
+ if (c->key_set)
+ CMAC_Update(c->cmac, iv, KEXP15_KUZNYECHIK_IV_PART);
+ }
+
+ if (key) {
+ c->key_set = 1;
+ const EVP_CIPHER *ciph = EVP_kuznyechik_cbc();
+ int kl = EVP_CIPHER_key_length(ciph);
+
+ if (!CMAC_Init(c->cmac, key, kl, ciph, NULL))
+ return 0;
+
+ if (iv != NULL)
+ CMAC_Update(c->cmac, iv, KEXP15_KUZNYECHIK_IV_PART);
+ else if (c->iv_set)
+ CMAC_Update(c->cmac, ctx->iv, KEXP15_KUZNYECHIK_IV_PART);
+
+ Kuznyechik_set_key(&c->ks, key + kl, 1);
+ }
+
+ return 1;
+}
+
+static int
+kuznyechik_kexp15_wrap_cleanup(EVP_CIPHER_CTX *ctx)
+{
+ EVP_KUZNYECHIK_KEXP15_WRAP_CTX *c = ctx->cipher_data;
+
+ CMAC_CTX_free(c->cmac);
+ c->iv_set = 0;
+ c->key_set = 0;
+
+ return 1;
+}
+
+static int
+kuznyechik_kexp15_wrap_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+ EVP_KUZNYECHIK_KEXP15_WRAP_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_KEXP15_WRAP_CTX, ctx);
+
+ switch (type) {
+ case EVP_CTRL_INIT:
+ key->cmac = CMAC_CTX_new();
+ key->iv_set = 0;
+ key->key_set = 0;
+ return 1;
+ default:
+ return kuznyechik_ctl(ctx, type, arg, ptr);
+ }
+}
+
+static int
+kuznyechik_kexp15_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+ size_t len)
+{
+ EVP_KUZNYECHIK_KEXP15_WRAP_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_KEXP15_WRAP_CTX, ctx);
+ unsigned char tmp[EVP_MAX_BLOCK_LENGTH];
+ size_t taglen = sizeof(tmp);
+ unsigned int bl = EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(key->cmac));
+
+ if (in == NULL)
+ return 0;
+
+ if (len % bl != 0)
+ return -1;
+ if (ctx->encrypt && len < bl)
+ return -1;
+ if (!ctx->encrypt && len < 2 *bl)
+ return -1;
+ if (out == NULL) {
+ if (ctx->encrypt)
+ return len + bl;
+ else
+ return len - bl;
+ }
+
+ /* Do not reuse IV */
+ key->iv_set = 0;
+
+ if (ctx->encrypt) {
+ CMAC_Update(key->cmac, in, len);
+ CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block128_f)Kuznyechik_encrypt);
+ CMAC_Final(key->cmac, tmp, &taglen);
+ CRYPTO_ctr128_encrypt(tmp, out + len, taglen, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block128_f)Kuznyechik_encrypt);
+ return len + taglen;
+ } else {
+ CRYPTO_ctr128_encrypt(in, out, len - bl, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block128_f)Kuznyechik_encrypt);
+ CMAC_Update(key->cmac, out, len - bl);
+ CMAC_Final(key->cmac, tmp, &taglen);
+ CRYPTO_ctr128_encrypt(tmp, tmp, taglen, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block128_f)Kuznyechik_encrypt);
+ return timingsafe_memcmp(in + len - bl, tmp, bl) ? -1 : len - bl;
+ }
+}
+
+static int
+kuznyechik_kexp15_wrap_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* FIXME: set key agreement OID, we need to pass it from upper layer */
+ return 1;
+}
+
+static int
+kuznyechik_kexp15_wrap_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* No useful information in ASN.1 params */
+ return 1;
+}
+
IMPLEMENT_BLOCK_CIPHER(kuznyechik, ks, Kuznyechik, EVP_KUZNYECHIK_CTX,
NID_kuznyechik, 16, 32, 16, 128, 0, kuznyechik_init_key, NULL,
EVP_CIPHER_set_asn1_iv,
@@ -375,6 +507,17 @@ BLOCK_CIPHER_def1(kuznyechik, ctr_acpkm_omac, ctr_acpkm_omac, CTR, EVP_KUZNYECHI
kuznyechik_ctr_acpkm_omac_get_asn1_params,
kuznyechik_ctr_acpkm_omac_ctl)
+#define NID_kuznyechik_kexp15_wrap NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15
+
+BLOCK_CIPHER_def1(kuznyechik, kexp15_wrap, kexp15_wrap, WRAP, EVP_KUZNYECHIK_KEXP15_WRAP_CTX,
+ NID_kuznyechik, 1, 64, 32,
+ EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT,
+ kuznyechik_kexp15_wrap_init_key,
+ kuznyechik_kexp15_wrap_cleanup,
+ kuznyechik_kexp15_wrap_set_asn1_params,
+ kuznyechik_kexp15_wrap_get_asn1_params,
+ kuznyechik_kexp15_wrap_ctl)
+
#define EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN 16
typedef struct {
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 48c7e7360..79ddcebc2 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -865,6 +865,7 @@ const EVP_CIPHER *EVP_kuznyechik_ofb(void);
const EVP_CIPHER *EVP_kuznyechik_ctr(void);
const EVP_CIPHER *EVP_kuznyechik_ctr_acpkm(void);
const EVP_CIPHER *EVP_kuznyechik_ctr_acpkm_omac(void);
+const EVP_CIPHER *EVP_kuznyechik_kexp15_wrap(void);
const EVP_CIPHER *EVP_kuznyechik_mgm(void);
#endif
--
2.17.1

View file

@ -0,0 +1,210 @@
From d621042e04e5f28f76720df8491c97f1a4307670 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 8 Apr 2020 18:09:14 +0300
Subject: [PATCH 58/87] evp: support magma kexp15 keywrap algorithm
Add support for magma kexp15 key wrapping algorithm
(draft-smyshlyaev-tls12-gost-suites, Section 8.2.1).
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/c_all.c | 1 +
src/lib/libcrypto/evp/e_magma.c | 143 ++++++++++++++++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 1 +
3 files changed, 145 insertions(+)
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index 482cc4e06..7afbb933e 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -236,6 +236,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_magma_ctr());
EVP_add_cipher(EVP_magma_ctr_acpkm());
EVP_add_cipher(EVP_magma_ctr_acpkm_omac());
+ EVP_add_cipher(EVP_magma_kexp15_wrap());
EVP_add_cipher(EVP_magma_mgm());
EVP_add_cipher(EVP_kuznyechik_ecb());
EVP_add_cipher(EVP_kuznyechik_cbc());
diff --git a/src/lib/libcrypto/evp/e_magma.c b/src/lib/libcrypto/evp/e_magma.c
index ffaeda505..c9e26deb5 100644
--- a/src/lib/libcrypto/evp/e_magma.c
+++ b/src/lib/libcrypto/evp/e_magma.c
@@ -42,6 +42,13 @@ typedef struct {
unsigned char tag[8];
} EVP_MAGMA_CTR_ACPKM_OMAC_CTX;
+typedef struct {
+ MAGMA_KEY ks;
+ CMAC_CTX *cmac;
+ int iv_set;
+ int key_set;
+} EVP_MAGMA_KEXP15_WRAP_CTX;
+
static int
magma_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
@@ -336,6 +343,131 @@ magma_ctr_acpkm_omac_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
return ret;
}
+#define KEXP15_IV_OFFSET 24
+#define KEXP15_MAGMA_IV_PART 4
+
+static int
+magma_kexp15_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_MAGMA_KEXP15_WRAP_CTX *c = ctx->cipher_data;
+
+ if (iv) {
+ memset(ctx->iv, 0, sizeof(ctx->iv));
+ memcpy(ctx->iv, iv + KEXP15_IV_OFFSET, KEXP15_MAGMA_IV_PART);
+ c->iv_set = 1;
+ if (c->key_set)
+ CMAC_Update(c->cmac, iv, KEXP15_MAGMA_IV_PART);
+ }
+
+ if (key) {
+ c->key_set = 1;
+ const EVP_CIPHER *ciph = EVP_magma_cbc();
+ int kl = EVP_CIPHER_key_length(ciph);
+
+ if (!CMAC_Init(c->cmac, key, kl, ciph, NULL))
+ return 0;
+
+ if (iv != NULL)
+ CMAC_Update(c->cmac, iv, KEXP15_MAGMA_IV_PART);
+ else if (c->iv_set)
+ CMAC_Update(c->cmac, ctx->iv, KEXP15_MAGMA_IV_PART);
+
+ Magma_set_key(&c->ks, key + 32);
+ }
+
+ return 1;
+}
+
+static int
+magma_kexp15_wrap_cleanup(EVP_CIPHER_CTX *ctx)
+{
+ EVP_MAGMA_KEXP15_WRAP_CTX *c = ctx->cipher_data;
+
+ CMAC_CTX_free(c->cmac);
+ c->iv_set = 0;
+ c->key_set = 0;
+
+ return 1;
+}
+
+static int
+magma_kexp15_wrap_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+ EVP_MAGMA_KEXP15_WRAP_CTX *key = EVP_C_DATA(EVP_MAGMA_KEXP15_WRAP_CTX, ctx);
+
+ switch (type) {
+ case EVP_CTRL_INIT:
+ key->cmac = CMAC_CTX_new();
+ key->iv_set = 0;
+ key->key_set = 0;
+ return 1;
+ default:
+ return magma_ctl(ctx, type, arg, ptr);
+ }
+}
+
+static int
+magma_kexp15_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+ size_t len)
+{
+ EVP_MAGMA_KEXP15_WRAP_CTX *key = EVP_C_DATA(EVP_MAGMA_KEXP15_WRAP_CTX, ctx);
+ unsigned char tmp[EVP_MAX_BLOCK_LENGTH];
+ size_t taglen = sizeof(tmp);
+ unsigned int bl = EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(key->cmac));
+
+ if (in == NULL)
+ return 0;
+
+ if (len % bl != 0)
+ return -1;
+ if (ctx->encrypt && len < bl)
+ return -1;
+ if (!ctx->encrypt && len < 2 *bl)
+ return -1;
+ if (out == NULL) {
+ if (ctx->encrypt)
+ return len + bl;
+ else
+ return len - bl;
+ }
+
+ /* Do not reuse IV */
+ key->iv_set = 0;
+
+ if (ctx->encrypt) {
+ CMAC_Update(key->cmac, in, len);
+ CRYPTO_ctr64_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_encrypt);
+ CMAC_Final(key->cmac, tmp, &taglen);
+ CRYPTO_ctr64_encrypt(tmp, out + len, taglen, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_encrypt);
+ return len + taglen;
+ } else {
+ CRYPTO_ctr64_encrypt(in, out, len - bl, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_encrypt);
+ CMAC_Update(key->cmac, out, len - bl);
+ CMAC_Final(key->cmac, tmp, &taglen);
+ CRYPTO_ctr64_encrypt(tmp, tmp, taglen, &key->ks, ctx->iv, ctx->buf,
+ &ctx->num, (block64_f)Magma_encrypt);
+ return timingsafe_memcmp(in + len - bl, tmp, bl) ? -1 : len - bl;
+ }
+}
+
+static int
+magma_kexp15_wrap_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* FIXME: set key agreement OID, we need to pass it from upper layer */
+ return 1;
+}
+
+static int
+magma_kexp15_wrap_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+ /* No useful information in ASN.1 params */
+ return 1;
+}
+
IMPLEMENT_BLOCK_CIPHER(magma, ks, Magma, EVP_MAGMA_CTX,
NID_magma, 8, 32, 8, 64, 0, magma_init_key, NULL,
EVP_CIPHER_set_asn1_iv,
@@ -369,6 +501,17 @@ BLOCK_CIPHER_def1(magma, ctr_acpkm_omac, ctr_acpkm_omac, CTR, EVP_MAGMA_CTR_ACPK
magma_ctr_acpkm_omac_get_asn1_params,
magma_ctr_acpkm_omac_ctl)
+#define NID_magma_kexp15_wrap NID_id_tc26_wrap_gostr3412_2015_magma_kexp15
+
+BLOCK_CIPHER_def1(magma, kexp15_wrap, kexp15_wrap, WRAP, EVP_MAGMA_KEXP15_WRAP_CTX,
+ NID_magma, 1, 64, 32,
+ EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT,
+ magma_kexp15_wrap_init_key,
+ magma_kexp15_wrap_cleanup,
+ magma_kexp15_wrap_set_asn1_params,
+ magma_kexp15_wrap_get_asn1_params,
+ magma_kexp15_wrap_ctl)
+
#define EVP_AEAD_MAGMA_MGM_TAG_LEN 16
typedef struct {
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 79ddcebc2..d5b78d8bd 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -857,6 +857,7 @@ const EVP_CIPHER *EVP_magma_ofb(void);
const EVP_CIPHER *EVP_magma_ctr(void);
const EVP_CIPHER *EVP_magma_ctr_acpkm(void);
const EVP_CIPHER *EVP_magma_ctr_acpkm_omac(void);
+const EVP_CIPHER *EVP_magma_kexp15_wrap(void);
const EVP_CIPHER *EVP_magma_mgm(void);
const EVP_CIPHER *EVP_kuznyechik_ecb(void);
const EVP_CIPHER *EVP_kuznyechik_cbc(void);
--
2.17.1

View file

@ -0,0 +1,144 @@
From cd0eec15fae54c7ca1b11109f85503b3cfb02217 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 8 Apr 2020 21:27:04 +0300
Subject: [PATCH 59/87] gost: support specifying old or new (KEG) derivation
format
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/gost/gost.h | 4 ++
src/lib/libcrypto/gost/gostr341001_pmeth.c | 68 +++++++++++++++++++++-
2 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index 6a2b60670..694906b76 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -229,6 +229,7 @@ size_t GOST_KEY_get_size(const GOST_KEY * r);
#define EVP_PKEY_CTRL_GOST_SET_DIGEST (EVP_PKEY_ALG_CTRL+3)
#define EVP_PKEY_CTRL_GOST_GET_DIGEST (EVP_PKEY_ALG_CTRL+4)
#define EVP_PKEY_CTRL_GOST_ENC_FORMAT (EVP_PKEY_ALG_CTRL+5)
+#define EVP_PKEY_CTRL_GOST_DERIVE_FORMAT (EVP_PKEY_ALG_CTRL+6)
#define GOST_SIG_FORMAT_SR_BE 0
#define GOST_SIG_FORMAT_RS_LE 1
@@ -237,6 +238,9 @@ size_t GOST_KEY_get_size(const GOST_KEY * r);
#define GOST_ENC_FORMAT_PSKEY_MAGMA 1 /* CMS, TLS CTR-OMAC, Magma-encoded */
#define GOST_ENC_FORMAT_PSKEY_KUZNYECHIK 2 /* CMS, TLS CTR-OMAC, Kuznyechik-encoded */
+#define GOST_DERIVE_FORMAT_4490 0 /* RFC 4490, TLS CNT-IMIT */
+#define GOST_DERIVE_FORMAT_KEG 1 /* CMS, TLS CTR-OMAC */
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c
index 07ca4d3a3..e21101ddc 100644
--- a/src/lib/libcrypto/gost/gostr341001_pmeth.c
+++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c
@@ -137,6 +137,7 @@ struct gost_pmeth_data {
int peer_key_used;
int sig_format;
int enc_format;
+ int derive_format;
};
static int
@@ -468,8 +469,8 @@ err:
return ret;
}
-int
-pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+static int
+pkey_gost01_derive_4490(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
/*
* Public key of peer in the ctx field peerkey
@@ -504,6 +505,38 @@ pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
return 1;
}
+static int
+pkey_gost01_derive_keg(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+{
+ /*
+ * Public key of peer in the ctx field peerkey
+ * Our private key in the ctx pkey
+ * ukm is in the algorithm specific context data
+ */
+ EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
+ EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
+ struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+
+ if (data->shared_ukm == NULL) {
+ GOSTerror(GOST_R_UKM_NOT_SET);
+ return 0;
+ }
+
+ if (key == NULL) {
+ *keylen = 64;
+ return 64;
+ }
+
+ if (!gost_keg(peer_key, my_key, data->digest_nid, data->shared_ukm, key)) {
+ GOSTerror(GOST_R_ERROR_COMPUTING_SHARED_KEY);
+ return 0;
+ }
+
+ *keylen = 64;
+
+ return 1;
+}
+
int
pkey_gost01_encrypt_4490(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len,
const unsigned char *key, size_t key_len)
@@ -816,6 +849,21 @@ pkey_gost01_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *out_len,
}
}
+int
+pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+{
+ struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx);
+
+ switch (pctx->derive_format) {
+ case GOST_DERIVE_FORMAT_4490:
+ return pkey_gost01_derive_4490(ctx, key, keylen);
+ case GOST_DERIVE_FORMAT_KEG:
+ return pkey_gost01_derive_keg(ctx, key, keylen);
+ default:
+ return -1;
+ }
+}
+
static int
pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
@@ -911,6 +959,22 @@ pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
pctx->enc_format = p1;
return 1;
break;
+ case EVP_PKEY_CTRL_GOST_DERIVE_FORMAT:
+ switch (p1) {
+ case GOST_DERIVE_FORMAT_4490:
+ /* All keys are supported */
+ break;
+ case GOST_DERIVE_FORMAT_KEG:
+ if (pctx->digest_nid != NID_id_tc26_gost3411_2012_256 &&
+ pctx->digest_nid != NID_id_tc26_gost3411_2012_512)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ pctx->derive_format = p1;
+ return 1;
+ break;
default:
return -2;
}
--
2.17.1

View file

@ -0,0 +1,72 @@
From 2cec22ef8cfe2df5aeb74861bf6ad4c621be6d02 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 9 Apr 2020 01:30:23 +0300
Subject: [PATCH 60/87] cms: add support for setting KeyAgreement UKM
Creating GOST KeyAgreement CMS files requires setting UKM. Add API
function to set it.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/cms/cms.h | 1 +
src/lib/libcrypto/cms/cms_kari.c | 17 +++++++++++++++++
3 files changed, 19 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index 3eda9f3bd..e5e7c435e 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -584,6 +584,7 @@ CMS_RecipientInfo_kari_get0_orig_id
CMS_RecipientInfo_kari_get0_reks
CMS_RecipientInfo_kari_orig_id_cmp
CMS_RecipientInfo_kari_set0_pkey
+CMS_RecipientInfo_kari_set0_ukm
CMS_RecipientInfo_kekri_get0_id
CMS_RecipientInfo_kekri_id_cmp
CMS_RecipientInfo_ktri_cert_cmp
diff --git a/src/lib/libcrypto/cms/cms.h b/src/lib/libcrypto/cms/cms.h
index 3c92be34f..fd2a5013a 100644
--- a/src/lib/libcrypto/cms/cms.h
+++ b/src/lib/libcrypto/cms/cms.h
@@ -324,6 +324,7 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid,
#endif
int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, X509_ALGOR **palg,
ASN1_OCTET_STRING **pukm);
+int CMS_RecipientInfo_kari_set0_ukm(CMS_RecipientInfo *ri, const unsigned char *d, int len);
STACK_OF(CMS_RecipientEncryptedKey) *
CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri);
diff --git a/src/lib/libcrypto/cms/cms_kari.c b/src/lib/libcrypto/cms/cms_kari.c
index 21e3ce825..2c3b50290 100644
--- a/src/lib/libcrypto/cms/cms_kari.c
+++ b/src/lib/libcrypto/cms/cms_kari.c
@@ -82,6 +82,23 @@ CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, X509_ALGOR **palg,
return 1;
}
+int
+CMS_RecipientInfo_kari_set0_ukm(CMS_RecipientInfo *ri, const unsigned char *d, int len)
+{
+ if (ri->type != CMS_RECIPINFO_AGREE) {
+ CMSerror(CMS_R_NOT_KEY_AGREEMENT);
+ return 0;
+ }
+ if (ri->d.kari->ukm == NULL)
+ ri->d.kari->ukm = ASN1_STRING_new();
+ if (ri->d.kari->ukm == NULL) {
+ CMSerror(ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ return ASN1_OCTET_STRING_set(ri->d.kari->ukm, d, len);
+}
+
/* Retrieve recipient encrypted keys from a kari */
STACK_OF(CMS_RecipientEncryptedKey) *
--
2.17.1

View file

@ -0,0 +1,41 @@
From 9500ec100b69ef59889bbd9aadffd986a99f9a9b Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 9 Apr 2020 01:32:30 +0300
Subject: [PATCH 61/87] cms: select proper cipher for GOST KeyAgreeement
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/cms/cms_kari.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/lib/libcrypto/cms/cms_kari.c b/src/lib/libcrypto/cms/cms_kari.c
index 2c3b50290..0082a7525 100644
--- a/src/lib/libcrypto/cms/cms_kari.c
+++ b/src/lib/libcrypto/cms/cms_kari.c
@@ -414,6 +414,7 @@ cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, const EVP_CIPHER *cipher)
EVP_CIPHER_CTX *ctx = kari->ctx;
const EVP_CIPHER *kekcipher;
int keylen = EVP_CIPHER_key_length(cipher);
+ int type = EVP_CIPHER_type(cipher);
/* If a suitable wrap algorithm is already set nothing to do */
kekcipher = EVP_CIPHER_CTX_cipher(ctx);
@@ -437,6 +438,15 @@ cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, const EVP_CIPHER *cipher)
kekcipher = EVP_des_ede3_wrap();
else
#endif
+#endif
+#ifndef OPENSSL_NO_GOST
+ if (type == NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm ||
+ type == NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac)
+ kekcipher = EVP_magma_kexp15_wrap();
+ else if (type == NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm ||
+ type == NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac)
+ kekcipher = EVP_kuznyechik_kexp15_wrap();
+ else
#endif
if (keylen <= 16)
kekcipher = EVP_aes_128_wrap();
--
2.17.1

View file

@ -0,0 +1,202 @@
From 01486becb95b03f8e62ecdadd268d48ceb452fcc Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 8 Apr 2020 21:28:10 +0300
Subject: [PATCH 62/87] cms: specify originator key for KeyAgreement decoding
Some CMS files with KeyAgreement will specify Originator using
IssuerAndSerialNumber or using SubjectKeyIdentifier. To decrypt these
files one needs originator certificate. Allow specifying it via
-certfile command line option.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/cms/cms.h | 2 ++
src/lib/libcrypto/cms/cms_asn1.c | 2 ++
src/lib/libcrypto/cms/cms_err.c | 1 +
src/lib/libcrypto/cms/cms_kari.c | 3 ++
src/lib/libcrypto/cms/cms_lcl.h | 2 ++
src/lib/libcrypto/cms/cms_smime.c | 53 +++++++++++++++++++++++++++++++
src/usr.bin/openssl/cms.c | 13 ++++++++
8 files changed, 77 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index e5e7c435e..ec3506131 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -627,6 +627,7 @@ CMS_dataInit
CMS_data_create
CMS_decrypt
CMS_decrypt_set1_key
+CMS_decrypt_set1_originator
CMS_decrypt_set1_password
CMS_decrypt_set1_pkey
CMS_digest_create
diff --git a/src/lib/libcrypto/cms/cms.h b/src/lib/libcrypto/cms/cms.h
index fd2a5013a..0c62536ec 100644
--- a/src/lib/libcrypto/cms/cms.h
+++ b/src/lib/libcrypto/cms/cms.h
@@ -198,6 +198,7 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms, unsigned char *key,
size_t keylen, const unsigned char *id, size_t idlen);
int CMS_decrypt_set1_password(CMS_ContentInfo *cms, unsigned char *pass,
ssize_t passlen);
+int CMS_decrypt_set1_originator(CMS_ContentInfo *cms, X509 *cert);
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
@@ -525,6 +526,7 @@ int ERR_load_CMS_strings(void);
#define CMS_R_UNWRAP_FAILURE 180
#define CMS_R_VERIFICATION_FAILURE 158
#define CMS_R_WRAP_ERROR 159
+#define CMS_R_NO_MATCHING_ORIGINATOR 160
#ifdef __cplusplus
}
diff --git a/src/lib/libcrypto/cms/cms_asn1.c b/src/lib/libcrypto/cms/cms_asn1.c
index ac53fec15..b3c02c07f 100644
--- a/src/lib/libcrypto/cms/cms_asn1.c
+++ b/src/lib/libcrypto/cms/cms_asn1.c
@@ -713,9 +713,11 @@ cms_kari_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
return 0;
EVP_CIPHER_CTX_set_flags(kari->ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
kari->pctx = NULL;
+ kari->originator_pkey = NULL;
} else if (operation == ASN1_OP_FREE_POST) {
EVP_PKEY_CTX_free(kari->pctx);
EVP_CIPHER_CTX_free(kari->ctx);
+ EVP_PKEY_free(kari->originator_pkey);
}
return 1;
}
diff --git a/src/lib/libcrypto/cms/cms_err.c b/src/lib/libcrypto/cms/cms_err.c
index 9b2abaa03..6b6112d46 100644
--- a/src/lib/libcrypto/cms/cms_err.c
+++ b/src/lib/libcrypto/cms/cms_err.c
@@ -278,6 +278,7 @@ static ERR_STRING_DATA CMS_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_VERIFICATION_FAILURE),
"verification failure"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_WRAP_ERROR), "wrap error"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_ORIGINATOR), "no matching originator"},
{0, NULL}
};
diff --git a/src/lib/libcrypto/cms/cms_kari.c b/src/lib/libcrypto/cms/cms_kari.c
index 0082a7525..145cc48dd 100644
--- a/src/lib/libcrypto/cms/cms_kari.c
+++ b/src/lib/libcrypto/cms/cms_kari.c
@@ -231,6 +231,9 @@ CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
pctx = EVP_PKEY_CTX_new(pk, NULL);
if (!pctx || !EVP_PKEY_derive_init(pctx))
goto err;
+ if (kari->originator_pkey)
+ if (EVP_PKEY_derive_set_peer(pctx, kari->originator_pkey) <= 0)
+ goto err;
kari->pctx = pctx;
return 1;
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h
index d400f5028..fa6c7660c 100644
--- a/src/lib/libcrypto/cms/cms_lcl.h
+++ b/src/lib/libcrypto/cms/cms_lcl.h
@@ -209,6 +209,8 @@ struct CMS_KeyAgreeRecipientInfo_st {
EVP_PKEY_CTX *pctx;
/* Cipher context for CEK wrapping */
EVP_CIPHER_CTX *ctx;
+ /* Originator's public key */
+ EVP_PKEY *originator_pkey;
};
struct CMS_OriginatorIdentifierOrKey_st {
diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c
index d02ec5db1..1a067c149 100644
--- a/src/lib/libcrypto/cms/cms_smime.c
+++ b/src/lib/libcrypto/cms/cms_smime.c
@@ -672,6 +672,59 @@ cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, EVP_PKEY *pk,
return 0;
}
+static int
+cms_kari_set1_peer(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+ X509 *cert)
+{
+ EVP_PKEY *pk = X509_get0_pubkey(cert);
+ if (!pk) {
+ CMSerror(CMS_R_ERROR_GETTING_PUBLIC_KEY);
+ return -1;
+ }
+
+ EVP_PKEY_up_ref(pk);
+ ri->d.kari->originator_pkey = pk;
+
+ return 1;
+}
+
+int
+CMS_decrypt_set1_originator(CMS_ContentInfo *cms, X509 *cert)
+{
+ STACK_OF(CMS_RecipientInfo) *ris;
+ CMS_RecipientInfo *ri;
+ int i, r, rv = 0;
+ int debug = 0;
+
+ ris = CMS_get0_RecipientInfos(cms);
+ if (ris)
+ debug = cms->d.envelopedData->encryptedContentInfo->debug;
+
+ for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+ int ri_type;
+
+ ri = sk_CMS_RecipientInfo_value(ris, i);
+ ri_type = CMS_RecipientInfo_type(ri);
+ if (ri_type == CMS_RECIPINFO_AGREE && !CMS_RecipientInfo_kari_orig_id_cmp(ri, cert)) {
+ r = cms_kari_set1_peer(cms, ri, cert);
+ if (r > 0)
+ rv = 1;
+ if (r < 0)
+ return 0;
+ }
+ }
+ /* If not debugging always return success */
+ if (!debug) {
+ ERR_clear_error();
+ return 1;
+ }
+
+ if (!rv)
+ CMSerror(CMS_R_NO_MATCHING_ORIGINATOR);
+
+ return rv;
+}
+
int
CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
{
diff --git a/src/usr.bin/openssl/cms.c b/src/usr.bin/openssl/cms.c
index cad855673..ada4c7746 100644
--- a/src/usr.bin/openssl/cms.c
+++ b/src/usr.bin/openssl/cms.c
@@ -947,6 +947,19 @@ cms_main(int argc, char **argv)
if (flags & CMS_DEBUG_DECRYPT)
CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
+ if (other) {
+ int i;
+ X509 *x;
+
+ for (i = 0; i < sk_X509_num(other); i++) {
+ x = sk_X509_value(other, i);
+ if (!CMS_decrypt_set1_originator(cms, x)) {
+ BIO_puts(bio_err,"Error setting CMS originator certificate\n");
+ goto end;
+ }
+ }
+ }
+
if (secret_key) {
if (!CMS_decrypt_set1_key(cms, secret_key,
secret_keylen, secret_keyid, secret_keyidlen)) {
--
2.17.1

View file

@ -0,0 +1,277 @@
From 4f8119d9168bfe32b03d31673425423d466f365c Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 9 Apr 2020 03:04:33 +0300
Subject: [PATCH 63/87] cms: support specifying originator certificate and key
during encryption
LibreSSL supports using ephemeral public key as Originator. Add support
for using other Originator types.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/cms/cms.h | 6 +++-
src/lib/libcrypto/cms/cms_env.c | 6 ++--
src/lib/libcrypto/cms/cms_kari.c | 45 +++++++++++++++++++++++--
src/lib/libcrypto/cms/cms_lcl.h | 3 +-
src/lib/libcrypto/cms/cms_smime.c | 3 +-
src/lib/libcrypto/ec/ec_ameth.c | 5 ++-
src/regress/lib/libcrypto/cms/cmstest.c | 2 +-
src/usr.bin/openssl/cms.c | 25 ++++++++++++--
8 files changed, 83 insertions(+), 12 deletions(-)
diff --git a/src/lib/libcrypto/cms/cms.h b/src/lib/libcrypto/cms/cms.h
index 0c62536ec..4084fd7da 100644
--- a/src/lib/libcrypto/cms/cms.h
+++ b/src/lib/libcrypto/cms/cms.h
@@ -125,6 +125,7 @@ int CMS_ContentInfo_print_ctx(BIO *out, CMS_ContentInfo *x, int indent, const AS
#define CMS_DEBUG_DECRYPT 0x20000
#define CMS_KEY_PARAM 0x40000
#define CMS_ASCIICRLF 0x80000
+#define CMS_USE_ORIGINATOR_KEYID 0x100000
const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms);
@@ -188,7 +189,9 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
- const EVP_CIPHER *cipher, unsigned int flags);
+ const EVP_CIPHER *cipher,
+ EVP_PKEY *originator_pkey, X509 *originator,
+ unsigned int flags);
int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
BIO *dcont, BIO *out, unsigned int flags);
@@ -205,6 +208,7 @@ int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip,
+ EVP_PKEY *originator_pkey, X509 *originator,
unsigned int flags);
int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
index 17778a4fe..b51baf702 100644
--- a/src/lib/libcrypto/cms/cms_env.c
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -238,7 +238,9 @@ cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk,
*/
CMS_RecipientInfo *
-CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags)
+CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip,
+ EVP_PKEY *originator_pkey, X509 *originator,
+ unsigned int flags)
{
CMS_RecipientInfo *ri = NULL;
CMS_EnvelopedData *env;
@@ -267,7 +269,7 @@ CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags)
break;
case CMS_RECIPINFO_AGREE:
- if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags))
+ if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator, originator_pkey, flags))
goto err;
break;
diff --git a/src/lib/libcrypto/cms/cms_kari.c b/src/lib/libcrypto/cms/cms_kari.c
index 145cc48dd..5a6e4b820 100644
--- a/src/lib/libcrypto/cms/cms_kari.c
+++ b/src/lib/libcrypto/cms/cms_kari.c
@@ -362,10 +362,33 @@ cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *pk)
return rv;
}
+/* Set the key from originator */
+static int
+cms_kari_set_originator_priv_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *pk)
+{
+ EVP_PKEY_CTX *pctx = NULL;
+ int rv = 0;
+
+ pctx = EVP_PKEY_CTX_new(pk, NULL);
+ if (!pctx)
+ goto err;
+ if (EVP_PKEY_derive_init(pctx) <= 0)
+ goto err;
+ kari->pctx = pctx;
+ rv = 1;
+
+ err:
+ if (!rv)
+ EVP_PKEY_CTX_free(pctx);
+
+ return rv;
+}
+
/* Initialise a kari based on passed certificate and key */
int
cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk,
+ X509 *originator, EVP_PKEY *originator_pkey,
unsigned int flags)
{
CMS_KeyAgreeRecipientInfo *kari;
@@ -401,9 +424,25 @@ cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk,
return 0;
}
- /* Create ephemeral key */
- if (!cms_kari_create_ephemeral_key(kari, pk))
- return 0;
+ if (originator_pkey == NULL && originator == NULL) {
+ /* Create ephemeral key */
+ if (!cms_kari_create_ephemeral_key(kari, pk))
+ return 0;
+ } else {
+ CMS_OriginatorIdentifierOrKey *oik = ri->d.kari->originator;
+
+ if (flags & CMS_USE_ORIGINATOR_KEYID) {
+ oik->type = CMS_OIK_KEYIDENTIFIER;
+ if (!cms_set1_keyid(&oik->d.subjectKeyIdentifier, originator))
+ return 0;
+ } else {
+ oik->type = CMS_OIK_ISSUER_SERIAL;
+ if (!cms_set1_ias(&oik->d.issuerAndSerialNumber, originator))
+ return 0;
+ }
+ if (!cms_kari_set_originator_priv_key(kari, originator_pkey))
+ return 0;
+ }
EVP_PKEY_up_ref(pk);
rek->pkey = pk;
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h
index fa6c7660c..e70c27e71 100644
--- a/src/lib/libcrypto/cms/cms_lcl.h
+++ b/src/lib/libcrypto/cms/cms_lcl.h
@@ -465,7 +465,8 @@ int cms_pkey_get_ri_type(EVP_PKEY *pk);
int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type);
/* KARI routines */
int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
- EVP_PKEY *pk, unsigned int flags);
+ EVP_PKEY *pk, X509 *originator, EVP_PKEY *originator_pkey,
+ unsigned int flags);
int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
/* PWRI routines */
diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c
index 1a067c149..dd1eb787b 100644
--- a/src/lib/libcrypto/cms/cms_smime.c
+++ b/src/lib/libcrypto/cms/cms_smime.c
@@ -612,6 +612,7 @@ CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey,
CMS_ContentInfo *
CMS_encrypt(STACK_OF(X509) *certs, BIO *data, const EVP_CIPHER *cipher,
+ EVP_PKEY *originator_pkey, X509 *originator,
unsigned int flags)
{
CMS_ContentInfo *cms;
@@ -623,7 +624,7 @@ CMS_encrypt(STACK_OF(X509) *certs, BIO *data, const EVP_CIPHER *cipher,
goto merr;
for (i = 0; i < sk_X509_num(certs); i++) {
recip = sk_X509_value(certs, i);
- if (!CMS_add1_recipient_cert(cms, recip, flags)) {
+ if (!CMS_add1_recipient_cert(cms, recip, originator_pkey, originator, flags)) {
CMSerror(CMS_R_RECIPIENT_ERROR);
goto err;
}
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
index 2e73bdd2f..a93a924bb 100644
--- a/src/lib/libcrypto/ec/ec_ameth.c
+++ b/src/lib/libcrypto/ec/ec_ameth.c
@@ -832,7 +832,10 @@ ecdh_cms_encrypt(CMS_RecipientInfo *ri)
if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
NULL, NULL, NULL))
goto err;
- X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+ if (talg == NULL)
+ aoid = NULL;
+ else
+ X509_ALGOR_get0(&aoid, NULL, NULL, talg);
/* Is everything uninitialised? */
if (aoid == OBJ_nid2obj(NID_undef)) {
diff --git a/src/regress/lib/libcrypto/cms/cmstest.c b/src/regress/lib/libcrypto/cms/cmstest.c
index 466583ecb..ca2619fc8 100644
--- a/src/regress/lib/libcrypto/cms/cmstest.c
+++ b/src/regress/lib/libcrypto/cms/cmstest.c
@@ -143,7 +143,7 @@ test_cms_encrypt_decrypt()
if ((bio_mem = BIO_new_mem_buf(cms_msg, -1)) == NULL)
errx(1, "failed to create BIO for message");
- if ((ci = CMS_encrypt(certs, bio_mem, EVP_aes_256_cbc(), 0)) == NULL) {
+ if ((ci = CMS_encrypt(certs, bio_mem, EVP_aes_256_cbc(), NULL, NULL, 0)) == NULL) {
fprintf(stderr, "FAIL: CMS_encrypt returned NULL\n");
ERR_print_errors_fp(stderr);
goto failure;
diff --git a/src/usr.bin/openssl/cms.c b/src/usr.bin/openssl/cms.c
index ada4c7746..a16987e93 100644
--- a/src/usr.bin/openssl/cms.c
+++ b/src/usr.bin/openssl/cms.c
@@ -246,6 +246,8 @@ cms_main(int argc, char **argv)
flags |= CMS_BINARY;
else if (!strcmp(*args, "-keyid"))
flags |= CMS_USE_KEYID;
+ else if (!strcmp(*args, "-origkeyid"))
+ flags |= CMS_USE_ORIGINATOR_KEYID;
else if (!strcmp(*args, "-nosigs"))
flags |= CMS_NOSIGS;
else if (!strcmp(*args, "-no_content_verify"))
@@ -590,6 +592,7 @@ cms_main(int argc, char **argv)
BIO_printf(bio_err, "-signer file signer certificate file\n");
BIO_printf(bio_err, "-recip file recipient certificate file for decryption\n");
BIO_printf(bio_err, "-keyid use subject key identifier\n");
+ BIO_printf(bio_err, "-origkeyid use originator's key identifier\n");
BIO_printf(bio_err, "-in file input file\n");
BIO_printf(bio_err, "-inform arg input format SMIME (default), PEM or DER\n");
BIO_printf(bio_err, "-inkey file input private key (if not signer or recipient)\n");
@@ -686,6 +689,9 @@ cms_main(int argc, char **argv)
if (operation == SMIME_DECRYPT) {
if (!keyfile)
keyfile = recipfile;
+ } else if (operation == SMIME_ENCRYPT) {
+ if (!keyfile)
+ keyfile = certfile;
} else if ((operation == SMIME_SIGN) ||
(operation == SMIME_SIGN_RECEIPT)) {
if (!keyfile)
@@ -797,8 +803,23 @@ cms_main(int argc, char **argv)
cms = CMS_compress(in, -1, flags);
} else if (operation == SMIME_ENCRYPT) {
int i;
+ X509 *orig = NULL;
+ if (other) {
+ if (!key) {
+ BIO_puts(bio_err,"Must specify CMS originator private key\n");
+ goto end;
+ }
+ if (sk_X509_num(other) != 1) {
+ BIO_puts(bio_err,"Must specify only CMS originator certificate\n");
+ goto end;
+ }
+ orig = sk_X509_value(other, 0);
+ } else if (key) {
+ BIO_puts(bio_err,"Must specify only CMS originator certificate (-certfile)\n");
+ goto end;
+ }
flags |= CMS_PARTIAL;
- cms = CMS_encrypt(NULL, in, cipher, flags);
+ cms = CMS_encrypt(NULL, in, cipher, key, orig, flags);
if (cms == NULL)
goto end;
for (i = 0; i < sk_X509_num(encerts); i++) {
@@ -812,7 +833,7 @@ cms_main(int argc, char **argv)
break;
}
}
- ri = CMS_add1_recipient_cert(cms, x, tflags);
+ ri = CMS_add1_recipient_cert(cms, x, key, orig, tflags);
if (ri == NULL)
goto end;
if (kparam != NULL) {
--
2.17.1

View file

@ -0,0 +1,411 @@
From bb3f59aa72cd62dd7fb3f99a36d42b75110f2a94 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 8 Apr 2020 21:27:46 +0300
Subject: [PATCH 64/87] gost: add support for decoding KeyAgreement CMS files
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/gost/gost.h | 1 +
src/lib/libcrypto/gost/gost_err.c | 1 +
src/lib/libcrypto/gost/gostr341001_ameth.c | 285 +++++++++++++++++++--
3 files changed, 263 insertions(+), 24 deletions(-)
diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h
index 694906b76..25beb4a8a 100644
--- a/src/lib/libcrypto/gost/gost.h
+++ b/src/lib/libcrypto/gost/gost.h
@@ -301,6 +301,7 @@ void ERR_load_GOST_strings(void);
#define GOST_R_SIGNATURE_MISMATCH 121
#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 122
#define GOST_R_UKM_NOT_SET 123
+#define GOST_R_NO_ORIGINATOR_CERTIFICATE 124
#ifdef __cplusplus
}
diff --git a/src/lib/libcrypto/gost/gost_err.c b/src/lib/libcrypto/gost/gost_err.c
index e7111dd34..ea734897c 100644
--- a/src/lib/libcrypto/gost/gost_err.c
+++ b/src/lib/libcrypto/gost/gost_err.c
@@ -96,6 +96,7 @@ static ERR_STRING_DATA GOST_str_reasons[] = {
{ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"},
{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
{ERR_REASON(GOST_R_UKM_NOT_SET) ,"ukm not set"},
+ {ERR_REASON(GOST_R_NO_ORIGINATOR_CERTIFICATE), "originator certificate not provided"},
{0, NULL}
};
#endif
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c b/src/lib/libcrypto/gost/gostr341001_ameth.c
index 965b36237..2b59642fe 100644
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ b/src/lib/libcrypto/gost/gostr341001_ameth.c
@@ -263,25 +263,24 @@ pkey_bits_gost01(const EVP_PKEY *pk)
}
static int
-pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
+pub_decode_gost01_int(EVP_PKEY *pk, X509_ALGOR *palg, const unsigned char *pubkey_buf, int pub_len)
{
- X509_ALGOR *palg = NULL;
- const unsigned char *pubkey_buf = NULL;
+ const ASN1_OBJECT *poid;
const unsigned char *p;
- ASN1_OBJECT *palgobj = NULL;
- int pub_len;
BIGNUM *X, *Y;
ASN1_OCTET_STRING *octet = NULL;
int len;
int ret;
int ptype = V_ASN1_UNDEF;
ASN1_STRING *pval = NULL;
+ int nid;
- if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)
- == 0)
+ X509_ALGOR_get0(&poid, &ptype, (const void **)&pval, palg);
+ nid = OBJ_obj2nid(poid);
+ if (nid != NID_id_GostR3410_2001 &&
+ nid != NID_id_tc26_gost3410_2012_256 &&
+ nid != NID_id_tc26_gost3410_2012_512)
return 0;
- (void)EVP_PKEY_assign_GOST(pk, NULL);
- X509_ALGOR_get0(NULL, &ptype, (const void **)&pval, palg);
if (ptype != V_ASN1_SEQUENCE) {
GOSTerror(GOST_R_BAD_KEY_PARAMETERS_FORMAT);
return 0;
@@ -315,26 +314,44 @@ pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
}
static int
-pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
+pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
+{
+ X509_ALGOR *palg = NULL;
+ const unsigned char *pubkey_buf = NULL;
+ int pub_len;
+
+ if (X509_PUBKEY_get0_param(NULL, &pubkey_buf, &pub_len, &palg, pub) == 0)
+ return 0;
+ (void)EVP_PKEY_assign_GOST(pk, NULL);
+
+ return pub_decode_gost01_int(pk, palg, pubkey_buf, pub_len);
+}
+
+static int
+pub_encode_gost01_int(const EVP_PKEY *pk, ASN1_OBJECT **palgobj, ASN1_STRING **pparams, unsigned char **pbuf, int *plen)
{
ASN1_OBJECT *algobj = NULL;
ASN1_OCTET_STRING *octet = NULL;
ASN1_STRING *params = NULL;
- void *pval = NULL;
unsigned char *buf = NULL, *sptr;
int key_size, ret = 0;
const EC_POINT *pub_key;
BIGNUM *X = NULL, *Y = NULL;
const GOST_KEY *ec = pk->pkey.gost;
- int ptype = V_ASN1_UNDEF;
+
+ *palgobj = NULL;
+ *pparams = NULL;
+ *pbuf = NULL;
+ *plen = 0;
algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec)));
+ if (algobj == NULL)
+ return 0;
+
if (pk->save_parameters) {
params = encode_gost01_algor_params(pk);
if (params == NULL)
- return 0;
- pval = params;
- ptype = V_ASN1_SEQUENCE;
+ goto err;
}
key_size = GOST_KEY_get_size(ec);
@@ -375,21 +392,44 @@ pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
GOST_bn2le(X, sptr, key_size);
GOST_bn2le(Y, sptr + key_size, key_size);
- BN_free(Y);
- BN_free(X);
-
ret = i2d_ASN1_OCTET_STRING(octet, &buf);
- ASN1_BIT_STRING_free(octet);
if (ret < 0)
- return 0;
+ goto err;
- return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
+ *palgobj = algobj;
+ *pparams = params;
+ *pbuf = buf;
+ *plen = ret;
+
+ return 1;
err:
BN_free(Y);
BN_free(X);
ASN1_BIT_STRING_free(octet);
ASN1_STRING_free(params);
+ ASN1_OBJECT_free(algobj);
+ return 0;
+}
+
+static int
+pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
+{
+ ASN1_OBJECT *algobj = NULL;
+ ASN1_STRING *params = NULL;
+ unsigned char *buf = NULL;
+ int len;
+
+ if (pub_encode_gost01_int(pk, &algobj, &params, &buf, &len) <= 0)
+ return 0;
+
+ if (X509_PUBKEY_set0_param(pub, algobj, V_ASN1_SEQUENCE, params, buf, len) == 1)
+ return 1;
+
+ free(buf);
+ ASN1_STRING_free(params);
+ ASN1_OBJECT_free(algobj);
+
return 0;
}
@@ -890,6 +930,89 @@ int gost01_smime_encrypt(EVP_PKEY_CTX *ctx, X509_ALGOR *alg, int enc_nid)
}
#ifndef OPENSSL_NO_CMS
+static int
+gost01_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg,
+ ASN1_BIT_STRING *pubkey)
+{
+ int rv = 0;
+ EVP_PKEY *pkpeer = NULL;
+ int ret;
+
+ pkpeer = EVP_PKEY_new();
+ if (pkpeer == NULL)
+ return 0;
+ (void)EVP_PKEY_assign_GOST(pkpeer, NULL);
+
+ ret = pub_decode_gost01_int(pkpeer, alg, pubkey->data, pubkey->length);
+ if (ret <= 0)
+ goto err;
+
+ if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
+ rv = 1;
+ err:
+
+ EVP_PKEY_free(pkpeer);
+ return rv;
+}
+
+static int
+gost01_cms_decrypt_kari(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
+{
+ EVP_CIPHER_CTX *kekctx;
+ X509_ALGOR *alg;
+ ASN1_OCTET_STRING *ukm;
+ const EVP_CIPHER *kekcipher;
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
+ return 0;
+
+ if (ukm == NULL)
+ return 0;
+
+ if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_SET_IV, ukm->length, ukm->data) < 0)
+ return 0;
+
+ if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
+ ASN1_BIT_STRING *pubkey;
+ X509_ALGOR *pkalg;
+
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &pkalg, &pubkey,
+ NULL, NULL, NULL))
+ return 0;
+ if (!pkalg || !pubkey) {
+ GOSTerror(GOST_R_NO_ORIGINATOR_CERTIFICATE);
+ return 0;
+ }
+ if (!gost01_cms_set_peerkey(pctx, pkalg, pubkey)) {
+ GOSTerror(GOST_R_INCOMPATIBLE_PEER_KEY);
+ return 0;
+ }
+ }
+
+ if (alg->parameter->type != V_ASN1_SEQUENCE)
+ return 0;
+
+ kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ if (!kekctx)
+ return 0;
+
+ kekcipher = EVP_get_cipherbyobj(alg->algorithm);
+ if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
+ return 0;
+ if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, ukm->data))
+ return 0;
+
+ if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_GOST_DERIVE_FORMAT,
+ GOST_DERIVE_FORMAT_KEG, NULL) <= 0) {
+ GOSTerror(ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
static int
gost01_cms_decrypt(CMS_RecipientInfo *ri)
{
@@ -899,12 +1022,116 @@ gost01_cms_decrypt(CMS_RecipientInfo *ri)
pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
if (pkctx == NULL)
return 0;
+ switch (CMS_RecipientInfo_type(ri)) {
+ case CMS_RECIPINFO_TRANS:
+ if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
+ return 0;
+ return gost01_smime_decrypt(pkctx, cmsalg);
+ case CMS_RECIPINFO_AGREE:
+ return gost01_cms_decrypt_kari(pkctx, ri);
+ default:
+ GOSTerror(ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+}
+
+static int
+gost01_cms_encrypt_kari(CMS_RecipientInfo *ri)
+{
+ EVP_PKEY_CTX *pctx;
+ EVP_PKEY *pkey;
+ EVP_CIPHER_CTX *ctx;
+ X509_ALGOR *talg, *wrap_alg = NULL;
+ ASN1_BIT_STRING *pubkey;
+ int wrap_nid;
+ unsigned char iv[32];
+ ASN1_STRING *params;
+
+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+ if (!pctx)
+ return 0;
- if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
+ /* Get ephemeral key */
+ pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+ if (pkey == NULL)
return 0;
- return gost01_smime_decrypt(pkctx, cmsalg);
+ if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_GOST_DERIVE_FORMAT,
+ GOST_DERIVE_FORMAT_KEG, NULL) <= 0) {
+ GOSTerror(ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
+ NULL, NULL, NULL))
+ goto err;
+
+ /* Ephemeral key */
+ if (talg) {
+ const ASN1_OBJECT *aoid = NULL;
+
+ X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+
+ /* Is everything uninitialised? */
+ if (aoid == OBJ_nid2obj(NID_undef)) {
+ ASN1_OBJECT *algobj = NULL;
+ ASN1_STRING *params = NULL;
+ unsigned char *buf = NULL;
+ int len;
+
+ if (pub_encode_gost01_int(pkey, &algobj, &params, &buf, &len) <= 0)
+ return 0;
+
+ X509_ALGOR_set0(talg, algobj, V_ASN1_SEQUENCE, params);
+ ASN1_STRING_set0(pubkey, buf, len);
+ }
+ }
+
+ /* Get wrap NID */
+ ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+ wrap_nid = EVP_CIPHER_CTX_type(ctx);
+
+ /* Package wrap algorithm in an AlgorithmIdentifier */
+
+ if (!CMS_RecipientInfo_kari_get0_alg(ri, &wrap_alg, NULL))
+ goto err;
+ if (wrap_alg == NULL)
+ goto err;
+ if ((params = encode_gost01_kexp_params(pkey)) == NULL)
+ goto err;
+ X509_ALGOR_set0(wrap_alg, OBJ_nid2obj(wrap_nid), V_ASN1_SEQUENCE, params);
+
+ arc4random_buf(iv, sizeof(iv));
+ if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_SET_IV, sizeof(iv), iv) < 0)
+ goto err;
+
+ if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1))
+ goto err;
+
+ if (!CMS_RecipientInfo_kari_set0_ukm(ri, iv, sizeof(iv)))
+ goto err;
+
+ return 1;
+err:
+ return 0;
+}
+
+static int
+gost01_cms_encrypt(CMS_RecipientInfo *ri)
+{
+ switch (CMS_RecipientInfo_type(ri)) {
+ case CMS_RECIPINFO_TRANS:
+ /* do nothing, handled in pmeth */
+ return 1;
+ case CMS_RECIPINFO_AGREE:
+ return gost01_cms_encrypt_kari(ri);
+ default:
+ return 0;
+ }
}
+
#endif
static int
@@ -921,9 +1148,19 @@ pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
&alg1, &alg2);
break;
case ASN1_PKEY_CTRL_CMS_ENVELOPE:
- if (arg1 == 1)
+ if (arg1 == 0)
+ return gost01_cms_encrypt(arg2);
+ else if (arg1 == 1)
return gost01_cms_decrypt(arg2);
break;
+ case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+ if (arg2 != NULL)
+ *(int *)arg2 = CMS_RECIPINFO_TRANS; /* default */
+ break;
+ case ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED:
+ if (arg2 != NULL)
+ *(int *)arg2 = (arg1 == CMS_RECIPINFO_TRANS || arg1 == CMS_RECIPINFO_AGREE);
+ break;
#endif
case ASN1_PKEY_CTRL_PKCS7_SIGN:
if (arg1 == 0)
--
2.17.1

View file

@ -0,0 +1,45 @@
From 2233c8980d35abd789e7fa0ba163bd1f10915f11 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 9 Apr 2020 03:16:06 +0300
Subject: [PATCH 65/87] cms: autoguess preferred RecipientInfo type
If caller has specified originator certificate and private keys, try
using KeyAgreeRecipientInfo, otherwise select pkey-preferred RI type.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/cms/cms_env.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
index b51baf702..8e025aa1d 100644
--- a/src/lib/libcrypto/cms/cms_env.c
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -245,6 +245,7 @@ CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip,
CMS_RecipientInfo *ri = NULL;
CMS_EnvelopedData *env;
EVP_PKEY *pk = NULL;
+ int ri_type;
env = cms_get0_enveloped(cms);
if (!env)
@@ -261,7 +262,13 @@ CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip,
goto err;
}
- switch (cms_pkey_get_ri_type(pk)) {
+ if (originator && originator_pkey &&
+ cms_pkey_is_ri_type_supported(pk, CMS_RECIPINFO_AGREE))
+ ri_type = CMS_RECIPINFO_AGREE;
+ else
+ ri_type = cms_pkey_get_ri_type(pk);
+
+ switch (ri_type) {
case CMS_RECIPINFO_TRANS:
if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
--
2.17.1

View file

@ -0,0 +1,41 @@
From 7d13acb589fd972be4522b5742e1a8a58349defd Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Thu, 19 Mar 2020 20:41:14 +0300
Subject: [PATCH 66/87] Fix S-Box used for CipherKeyExchange message in GOST
ciphersuites
GOST TLS CipherSuites are oververbose. One of implementations ignored
OID of the s-box that was sent as a part of the messages and used
calculated one, which differs from the one used by LibreSSL. Let
LibreSSL code also calculate proper S-Box and use it during key
exchange.
See https://github.com/libressl-portable/portable/issues/396
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/gost/gostr341001_pmeth.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c
index e21101ddc..2813f312c 100644
--- a/src/lib/libcrypto/gost/gostr341001_pmeth.c
+++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c
@@ -548,7 +548,13 @@ pkey_gost01_encrypt_4490(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len
int ret = 0;
int key_is_ephemeral;
EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx);
- int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
+ int nid;
+
+ if (GOST_KEY_get_digest(pubk->pkey.gost) ==
+ NID_id_GostR3411_94_CryptoProParamSet)
+ nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
+ else
+ nid = NID_id_tc26_gost_28147_param_Z;
if (data->shared_ukm != NULL && data->shared_ukm_len >= 8) {
memcpy(ukm, data->shared_ukm, 8);
--
2.17.1

View file

@ -0,0 +1,46 @@
From acd13e2112724fee3e495cf866b4b19ebf64db91 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 17 Apr 2020 04:09:25 +0300
Subject: [PATCH 67/87] gost: pmeth: check that result of data encryption would
fit
Check that the result of PKEY_ENCRYPT operation won't overflow provided data
buffer.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/gost/gostr341001_pmeth.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c
index 2813f312c..5f99cf8e1 100644
--- a/src/lib/libcrypto/gost/gostr341001_pmeth.c
+++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c
@@ -549,6 +549,7 @@ pkey_gost01_encrypt_4490(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len
int key_is_ephemeral;
EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx);
int nid;
+ int tmp_len;
if (GOST_KEY_get_digest(pubk->pkey.gost) ==
NID_id_GostR3411_94_CryptoProParamSet)
@@ -635,7 +636,15 @@ pkey_gost01_encrypt_4490(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len
goto err;
}
}
- if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0)
+ tmp_len = i2d_GOST_KEY_TRANSPORT(gkt, NULL);
+ if (!out) {
+ *out_len = tmp_len;
+ } else {
+ if (*out_len < tmp_len)
+ goto err;
+ *out_len = i2d_GOST_KEY_TRANSPORT(gkt, &out);
+ }
+ if (out_len > 0)
ret = 1;
GOST_KEY_TRANSPORT_free(gkt);
return ret;
--
2.17.1

View file

@ -0,0 +1,146 @@
From d0051e736d9d643dbd3977b472bf011eb4f37cb3 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 27 Mar 2020 18:25:51 +0300
Subject: [PATCH 68/87] ssl_sigalgs: select proper default algorithm for GOST
pkeys
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 <dbaryshkov@gmail.com>
---
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 6378ec8c0..224c01af0 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, &nid))
+ 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, &nid)) {
+ 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 fe500a9d6..58955cd78 100644
--- a/src/regress/lib/libssl/tlsext/tlsexttest.c
+++ b/src/regress/lib/libssl/tlsext/tlsexttest.c
@@ -1506,9 +1506,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
@@ -2713,13 +2714,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.17.1

View file

@ -0,0 +1,109 @@
From d7cd5bfb3c079b3df01fa1c67cabc6194e4c31ce Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sat, 28 Mar 2020 22:19:05 +0300
Subject: [PATCH 69/87] ssl: add support for IANA-allocated GOST sigalgs values
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 <dbaryshkov@gmail.com>
---
src/lib/libssl/ssl_sigalgs.c | 12 ++++++++++++
src/lib/libssl/ssl_sigalgs.h | 2 ++
src/regress/lib/libssl/tlsext/tlsexttest.c | 13 +++++++------
3 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/src/lib/libssl/ssl_sigalgs.c b/src/lib/libssl/ssl_sigalgs.c
index 224c01af0..ffa6278eb 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 13a3597fb..5fe3fc3bb 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
diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c b/src/regress/lib/libssl/tlsext/tlsexttest.c
index 58955cd78..23a922893 100644
--- a/src/regress/lib/libssl/tlsext/tlsexttest.c
+++ b/src/regress/lib/libssl/tlsext/tlsexttest.c
@@ -1506,10 +1506,11 @@ test_tlsext_ri_server(void)
*/
static unsigned char tlsext_sigalgs_client[] = {
- 0x00, 0x1c, 0x08, 0x06, 0x06, 0x01, 0x06, 0x03,
+ 0x00, 0x20, 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,
+ 0x08, 0x41, 0xef, 0xef, 0x08, 0x40, 0xee, 0xee,
+ 0xed, 0xed,
};
static int
@@ -2714,14 +2715,14 @@ test_tlsext_srtp_server(void)
#endif /* OPENSSL_NO_SRTP */
unsigned char tlsext_clienthello_default[] = {
- 0x00, 0x38, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
+ 0x00, 0x3c, 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, 0x1e, 0x00, 0x1c, 0x08, 0x06,
+ 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, 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,
+ 0x02, 0x01, 0x02, 0x03, 0x08, 0x41, 0xef, 0xef,
+ 0x08, 0x40, 0xee, 0xee, 0xed, 0xed,
};
unsigned char tlsext_clienthello_disabled[] = {};
--
2.17.1

View file

@ -0,0 +1,40 @@
From fea5c236fbb0ee848bf6d7044f64042fa511e86f Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sat, 28 Mar 2020 22:33:33 +0300
Subject: [PATCH 70/87] ssl: provide interoperability with CryptoPro CSP
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 <dbaryshkov@gmail.com>
---
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 ffa6278eb..97a0b71fc 100644
--- a/src/lib/libssl/ssl_sigalgs.c
+++ b/src/lib/libssl/ssl_sigalgs.c
@@ -379,6 +379,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.17.1

View file

@ -0,0 +1,31 @@
From 93770e5b55266895828fdfb26e6f095b98ded435 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sun, 29 Mar 2020 00:02:52 +0300
Subject: [PATCH 71/87] ssl: do not send GOST 94 certificate type
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 <dbaryshkov@gmail.com>
---
src/lib/libssl/tls1.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/lib/libssl/tls1.h b/src/lib/libssl/tls1.h
index 8cd522658..b3bf1687a 100644
--- a/src/lib/libssl/tls1.h
+++ b/src/lib/libssl/tls1.h
@@ -735,7 +735,6 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
#define TLS_CT_DSS_SIGN 2
#define TLS_CT_RSA_FIXED_DH 3
#define TLS_CT_DSS_FIXED_DH 4
-#define TLS_CT_GOST94_SIGN 21
#define TLS_CT_GOST01_SIGN 22
#define TLS_CT_ECDSA_SIGN 64
#define TLS_CT_RSA_FIXED_ECDH 65
--
2.17.1

View file

@ -0,0 +1,47 @@
From fb0bffd55cfc46f60848a22e7f351cb23b47ca3a Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sun, 29 Mar 2020 00:24:35 +0300
Subject: [PATCH 72/87] ssl: add support for new GOST CNT-IMIT ciphersuite
value
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 <dbaryshkov@gmail.com>
---
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 e2fef7258..425420c4a 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.17.1

View file

@ -0,0 +1,89 @@
From 87ce8af5f7de65351fd0c7914416539ad091d86b Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Tue, 31 Mar 2020 21:16:51 +0300
Subject: [PATCH 73/87] evp: add EVP_PKEY_new_CMAC_key function
Add a function to initialize EVP_PKEY for CMAC operations. CMAC already
exports necessary pmeths, but it is not possible to use it throught
EVP_PKEY_new_mac_type().
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/Symbols.list | 1 +
src/lib/libcrypto/evp/evp.h | 3 +++
src/lib/libcrypto/evp/p_lib.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 35 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index ec3506131..a1c4a0961 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1589,6 +1589,7 @@ EVP_PKEY_meth_set_verify_recover
EVP_PKEY_meth_set_verifyctx
EVP_PKEY_missing_parameters
EVP_PKEY_new
+EVP_PKEY_new_CMAC_key
EVP_PKEY_new_mac_key
EVP_PKEY_paramgen
EVP_PKEY_paramgen_init
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index d5b78d8bd..8ec5a5647 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1173,6 +1173,9 @@ void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key,
int keylen);
+EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+ size_t len, const EVP_CIPHER *cipher);
+
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
diff --git a/src/lib/libcrypto/evp/p_lib.c b/src/lib/libcrypto/evp/p_lib.c
index 13a9d65f2..262515247 100644
--- a/src/lib/libcrypto/evp/p_lib.c
+++ b/src/lib/libcrypto/evp/p_lib.c
@@ -255,6 +255,37 @@ pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
return 1;
}
+EVP_PKEY *
+EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+ size_t len, const EVP_CIPHER *cipher)
+{
+#ifndef OPENSSL_NO_CMAC
+ EVP_PKEY_CTX *mac_ctx = NULL;
+ EVP_PKEY *mac_key = NULL;
+
+ mac_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_CMAC, e);
+ if (!mac_ctx)
+ return NULL;
+ if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
+ goto merr;
+ if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
+ EVP_PKEY_CTRL_CIPHER, 0, (void *)cipher) <= 0)
+ goto merr;
+ if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
+ EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)priv) <= 0)
+ goto merr;
+ if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
+ goto merr;
+
+merr:
+ EVP_PKEY_CTX_free(mac_ctx);
+ return mac_key;
+#else
+ EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return NULL;
+#endif
+}
+
int
EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
{
--
2.17.1

View file

@ -0,0 +1,77 @@
From 8fc7a6230875bd0d6290df4670680ce687f7daf6 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Tue, 31 Mar 2020 21:19:10 +0300
Subject: [PATCH 74/87] evp: fix sign/verify for EVP_PKEY_CMAC keys
Properly handle EVP_PKEY_FLAG_SIGCTX_CUSTOM flag to support
EVP_PKEY_CMAC keys.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/m_sigver.c | 33 ++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/lib/libcrypto/evp/m_sigver.c b/src/lib/libcrypto/evp/m_sigver.c
index 9e313c363..fbe107020 100644
--- a/src/lib/libcrypto/evp/m_sigver.c
+++ b/src/lib/libcrypto/evp/m_sigver.c
@@ -74,15 +74,17 @@ do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
if (ctx->pctx == NULL)
return 0;
- if (type == NULL) {
- int def_nid;
- if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
- type = EVP_get_digestbynid(def_nid);
- }
+ if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
+ if (type == NULL) {
+ int def_nid;
+ if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+ type = EVP_get_digestbynid(def_nid);
+ }
- if (type == NULL) {
- EVPerror(EVP_R_NO_DEFAULT_DIGEST);
- return 0;
+ if (type == NULL) {
+ EVPerror(EVP_R_NO_DEFAULT_DIGEST);
+ return 0;
+ }
}
if (ver) {
@@ -103,6 +105,8 @@ do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
}
if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
return 0;
+ if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
+ return 1;
if (pctx)
*pctx = ctx->pctx;
if (!EVP_DigestInit_ex(ctx, type, e))
@@ -129,6 +133,19 @@ EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
{
int sctx, r = 0;
+ if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
+ EVP_PKEY_CTX *dctx;
+
+ if (!sigret)
+ return ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx);
+
+ dctx = EVP_PKEY_CTX_dup(ctx->pctx);
+ if (!dctx)
+ return 0;
+ r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
+ EVP_PKEY_CTX_free(dctx);
+ return r;
+ }
if (ctx->pctx->pmeth->signctx)
sctx = 1;
else
--
2.17.1

View file

@ -0,0 +1,49 @@
From 9793963c8430257904121816af0125b7607582c7 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Tue, 31 Mar 2020 21:22:19 +0300
Subject: [PATCH 75/87] evp: fix EVP_MD_CTX_copy_ex for CMAC contexts
EVP_MD_CTX created for EVP_PKEY_CMAC will not have ctx->digest even when
fully initialized. Support copying of such contexts.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/evp/digest.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/lib/libcrypto/evp/digest.c b/src/lib/libcrypto/evp/digest.c
index 4cd3565c6..15192a813 100644
--- a/src/lib/libcrypto/evp/digest.c
+++ b/src/lib/libcrypto/evp/digest.c
@@ -260,7 +260,7 @@ EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
{
unsigned char *tmp_buf;
- if ((in == NULL) || (in->digest == NULL)) {
+ if (in == NULL) {
EVPerror(EVP_R_INPUT_NOT_INITIALIZED);
return 0;
}
@@ -280,7 +280,7 @@ EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
EVP_MD_CTX_cleanup(out);
memcpy(out, in, sizeof *out);
- if (in->md_data && out->digest->ctx_size) {
+ if (in->md_data && out->digest && out->digest->ctx_size) {
if (tmp_buf) {
out->md_data = tmp_buf;
} else {
@@ -303,7 +303,7 @@ EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
}
}
- if (out->digest->copy)
+ if (out->digest && out->digest->copy)
return out->digest->copy(out, in);
return 1;
--
2.17.1

View file

@ -0,0 +1,36 @@
From fec0b1cb566c95bda198cc10b9ff8b82e607d6d0 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 17:05:57 +0300
Subject: [PATCH 76/87] objects: add id for gost-kdf key exchange (for
CTR-OMAC)
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/objects/obj_mac.num | 1 +
src/lib/libcrypto/objects/objects.txt | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num
index 6e494cb92..2985c4f0f 100644
--- a/src/lib/libcrypto/objects/obj_mac.num
+++ b/src/lib/libcrypto/objects/obj_mac.num
@@ -1021,3 +1021,4 @@ id_tc26_agreement_gost_3410_12_512 1020
id_tc26_wrap_gostr3412_2015_magma_kexp15 1021
id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1022
id_cms_mac_attr 1023
+kx_gost_kdf 1024
diff --git a/src/lib/libcrypto/objects/objects.txt b/src/lib/libcrypto/objects/objects.txt
index 3f810dcf8..9139907cd 100644
--- a/src/lib/libcrypto/objects/objects.txt
+++ b/src/lib/libcrypto/objects/objects.txt
@@ -1436,6 +1436,7 @@ tc26 1 7 2 1 : id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15
: KxECDHE : kx-ecdhe
: KxDHE : kx-dhe
: KxGOST : kx-gost
+ : KxGOSTKDF : kx-gost-kdf
# TLS cipher suite authentication
: AuthRSA : auth-rsa
--
2.17.1

View file

@ -0,0 +1,211 @@
From 2ed69ca1219dd8287476bed0d20d50750c010d11 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 17:10:52 +0300
Subject: [PATCH 77/87] ssl: add defines for GOST CTR-OMAC ciphersuites
Add definitions for cipher, mac and KX used by GOST CTR-OMAC
ciphersuites (see draft-smyshlyaev-tls12-gost-suites-07).
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/s3_lib.c | 32 ++++++++++++++++++++++++++++++++
src/lib/libssl/ssl.h | 3 +++
src/lib/libssl/ssl_ciph.c | 38 ++++++++++++++++++++++++++++++++++++++
src/lib/libssl/ssl_locl.h | 5 +++++
4 files changed, 78 insertions(+)
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index 425420c4a..18b9ad62f 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1305,6 +1305,38 @@ SSL_CIPHER ssl3_ciphers[] = {
.alg_bits = 256,
},
+ /* Cipher C100 */
+ {
+ .valid = 1,
+ .name = "GOST2012256-KUZNYECHIK-CTR-OMAC",
+ .id = 0x300c100,
+ .algorithm_mkey = SSL_kGOST_KDF,
+ .algorithm_auth = SSL_aGOST01,
+ .algorithm_enc = SSL_KUZNYECHIK_CTR_ACPKM,
+ .algorithm_mac = SSL_KUZNYECHIK_OMAC,
+ .algorithm_ssl = SSL_TLSV1_2,
+ .algo_strength = SSL_HIGH,
+ .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256,
+ .strength_bits = 256,
+ .alg_bits = 256
+ },
+
+ /* Cipher C101 */
+ {
+ .valid = 1,
+ .name = "GOST2012256-MAGMA-CTR-OMAC",
+ .id = 0x300c101,
+ .algorithm_mkey = SSL_kGOST_KDF,
+ .algorithm_auth = SSL_aGOST01,
+ .algorithm_enc = SSL_MAGMA_CTR_ACPKM,
+ .algorithm_mac = SSL_MAGMA_OMAC,
+ .algorithm_ssl = SSL_TLSV1_2,
+ .algo_strength = SSL_HIGH,
+ .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256,
+ .strength_bits = 256,
+ .alg_bits = 256
+ },
+
/* Cipher C102 */
{
.valid = 1,
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index 4370c84cd..b11216b1e 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -246,6 +246,7 @@ extern "C" {
#define SSL_TXT_kEECDH "kEECDH"
#define SSL_TXT_kPSK "kPSK"
#define SSL_TXT_kGOST "kGOST"
+#define SSL_TXT_kGOST_KDF "kGOSTKDF"
#define SSL_TXT_kSRP "kSRP"
#define SSL_TXT_aRSA "aRSA"
@@ -299,6 +300,8 @@ extern "C" {
#define SSL_TXT_SHA384 "SHA384"
#define SSL_TXT_STREEBOG256 "STREEBOG256"
#define SSL_TXT_STREEBOG512 "STREEBOG512"
+#define SSL_TXT_KUZNYECHIK_OMAC "KUZNYECHIK-OMAC"
+#define SSL_TXT_MAGMA_OMAC "MAGMA-OMAC"
#define SSL_TXT_DTLS1 "DTLSv1"
#define SSL_TXT_SSLV2 "SSLv2"
diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c
index 37417efc0..9ef17e052 100644
--- a/src/lib/libssl/ssl_ciph.c
+++ b/src/lib/libssl/ssl_ciph.c
@@ -219,6 +219,11 @@ static const SSL_CIPHER cipher_aliases[] = {
.algorithm_mkey = SSL_kGOST,
},
+ {
+ .name = SSL_TXT_kGOST_KDF,
+ .algorithm_mkey = SSL_kGOST_KDF,
+ },
+
/* server authentication aliases */
{
.name = SSL_TXT_aRSA,
@@ -365,6 +370,14 @@ static const SSL_CIPHER cipher_aliases[] = {
.name = SSL_TXT_GOST89MAC,
.algorithm_mac = SSL_GOST89MAC,
},
+ {
+ .name = SSL_TXT_KUZNYECHIK_OMAC,
+ .algorithm_mac = SSL_KUZNYECHIK_OMAC,
+ },
+ {
+ .name = SSL_TXT_MAGMA_OMAC,
+ .algorithm_mac = SSL_MAGMA_OMAC,
+ },
{
.name = SSL_TXT_SHA256,
.algorithm_mac = SSL_SHA256,
@@ -1424,6 +1437,9 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_kGOST:
kx = "GOST";
break;
+ case SSL_kGOST_KDF:
+ kx = "GOSTKDF";
+ break;
case SSL_kTLS1_3:
kx = "TLSv1.3";
break;
@@ -1489,6 +1505,12 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_eGOST2814789CNT:
enc = "GOST-28178-89-CNT";
break;
+ case SSL_KUZNYECHIK_CTR_ACPKM:
+ enc = "KUZNYECHIK-CTR-ACPKM";
+ break;
+ case SSL_MAGMA_CTR_ACPKM:
+ enc = "MAGMA-CTR-ACPKM";
+ break;
default:
enc = "unknown";
break;
@@ -1519,6 +1541,12 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_STREEBOG256:
mac = "STREEBOG256";
break;
+ case SSL_KUZNYECHIK_OMAC:
+ mac = "KUZNYECHIK-OMAC";
+ break;
+ case SSL_MAGMA_OMAC:
+ mac = "MAGMA-OMAC";
+ break;
default:
mac = "unknown";
break;
@@ -1613,6 +1641,10 @@ SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c)
return NID_rc4;
case SSL_eGOST2814789CNT:
return NID_gost89_cnt;
+ case SSL_KUZNYECHIK_CTR_ACPKM:
+ return NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm;
+ case SSL_MAGMA_CTR_ACPKM:
+ return NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm;
default:
return NID_undef;
}
@@ -1638,6 +1670,10 @@ SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c)
return NID_sha384;
case SSL_STREEBOG256:
return NID_id_tc26_gost3411_2012_256;
+ case SSL_KUZNYECHIK_OMAC:
+ return NID_kuznyechik_mac;
+ case SSL_MAGMA_OMAC:
+ return NID_magma_mac;
default:
return NID_undef;
}
@@ -1653,6 +1689,8 @@ SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c)
return NID_kx_ecdhe;
case SSL_kGOST:
return NID_kx_gost;
+ case SSL_kGOST_KDF:
+ return NID_kx_gost_kdf;
case SSL_kRSA:
return NID_kx_rsa;
default:
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index bfc3c1ad9..72646fa8c 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -206,6 +206,7 @@ __BEGIN_HIDDEN_DECLS
#define SSL_kECDHE 0x00000080L /* ephemeral ECDH */
#define SSL_kGOST 0x00000200L /* GOST key exchange */
#define SSL_kTLS1_3 0x00000400L /* TLSv1.3 key exchange */
+#define SSL_kGOST_KDF 0x00000800L /* GOST KDF key exchange */
/* Bits for algorithm_auth (server authentication) */
#define SSL_aRSA 0x00000001L /* RSA auth */
@@ -229,6 +230,8 @@ __BEGIN_HIDDEN_DECLS
#define SSL_AES128GCM 0x00000400L
#define SSL_AES256GCM 0x00000800L
#define SSL_CHACHA20POLY1305 0x00001000L
+#define SSL_KUZNYECHIK_CTR_ACPKM 0x00002000L
+#define SSL_MAGMA_CTR_ACPKM 0x00004000L
#define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM)
#define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256)
@@ -245,6 +248,8 @@ __BEGIN_HIDDEN_DECLS
/* Not a real MAC, just an indication it is part of cipher */
#define SSL_AEAD 0x00000040L
#define SSL_STREEBOG256 0x00000080L
+#define SSL_KUZNYECHIK_OMAC 0x00000100L
+#define SSL_MAGMA_OMAC 0x00000200L
/* Bits for algorithm_ssl (protocol version) */
#define SSL_SSLV3 0x00000002L
--
2.17.1

View file

@ -0,0 +1,411 @@
From e2409a33a5ffb21c41de9f213fecaf26e384d6a8 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 17:15:42 +0300
Subject: [PATCH 78/87] ssl: add support for GOST-KDF key exchange
Add support for GOST-KDF key exchange used by CTR-OMAC cipher suites.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/s3_lib.c | 2 +
src/lib/libssl/ssl_ciph.c | 2 +-
src/lib/libssl/ssl_clnt.c | 87 +++++++++++++++++++---------------
src/lib/libssl/ssl_lib.c | 2 +-
src/lib/libssl/ssl_locl.h | 2 +
src/lib/libssl/ssl_srvr.c | 98 +++++++++++++++++++++++++--------------
src/lib/libssl/t1_lib.c | 42 +++++++++++++++++
7 files changed, 162 insertions(+), 73 deletions(-)
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index 18b9ad62f..106a2567a 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -2598,6 +2598,8 @@ ssl3_get_req_cert_types(SSL *s, CBB *cbb)
if ((alg_k & SSL_kGOST) != 0) {
if (!CBB_add_u8(cbb, TLS_CT_GOST01_SIGN))
return 0;
+ }
+ if (((alg_k & SSL_kGOST) != 0) || ((alg_k & SSL_kGOST_KDF) != 0)) {
if (!CBB_add_u8(cbb, TLS_CT_GOST12_256_SIGN))
return 0;
if (!CBB_add_u8(cbb, TLS_CT_GOST12_512_SIGN))
diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c
index 9ef17e052..a3e0d396b 100644
--- a/src/lib/libssl/ssl_ciph.c
+++ b/src/lib/libssl/ssl_ciph.c
@@ -653,7 +653,7 @@ ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth,
*/
if (EVP_PKEY_meth_find(NID_id_GostR3410_2001) == NULL) {
*auth |= SSL_aGOST01;
- *mkey |= SSL_kGOST;
+ *mkey |= SSL_kGOST | SSL_kGOST_KDF;
}
#ifdef SSL_FORBID_ENULL
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c
index 0a1b6ea24..731104253 100644
--- a/src/lib/libssl/ssl_clnt.c
+++ b/src/lib/libssl/ssl_clnt.c
@@ -2141,18 +2141,14 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sc, CBB *cbb)
}
static int
-ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
+ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, CBB *cbb, unsigned int psexp)
{
- unsigned char premaster_secret[32], shared_ukm[32], tmp[256];
+ unsigned char premaster_secret[32], *tmp = NULL;
EVP_PKEY *pub_key = NULL;
EVP_PKEY_CTX *pkey_ctx;
X509 *peer_cert;
size_t msglen;
- unsigned int md_len;
- EVP_MD_CTX *ukm_hash;
int ret = -1;
- int nid;
- CBB gostblob;
/* Get server sertificate PKEY and create ctx from it */
peer_cert = sess_cert->peer_pkeys[SSL_PKEY_GOST01].x509;
@@ -2172,12 +2168,13 @@ ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
EVP_PKEY_encrypt_init(pkey_ctx);
/* Generate session key. */
- arc4random_buf(premaster_secret, 32);
+ arc4random_buf(premaster_secret, sizeof(premaster_secret));
/*
* If we have client certificate, use its secret as peer key.
+ * Only for old (non-PSexp) key exchange.
*/
- if (S3I(s)->tmp.cert_req && s->cert->key->privatekey) {
+ if (!psexp && S3I(s)->tmp.cert_req && s->cert->key->privatekey) {
if (EVP_PKEY_derive_set_peer(pkey_ctx,
s->cert->key->privatekey) <=0) {
/*
@@ -2186,49 +2183,62 @@ ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
*/
ERR_clear_error();
}
+ } else if (psexp) {
+ int format;
+
+ if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_MAGMA_CTR_ACPKM)
+ format = GOST_ENC_FORMAT_PSKEY_MAGMA;
+ else
+ format = GOST_ENC_FORMAT_PSKEY_KUZNYECHIK;
+
+ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT,
+ EVP_PKEY_CTRL_GOST_ENC_FORMAT,
+ format, NULL) <= 0) {
+ SSLerror(s, ERR_R_EVP_LIB);
+ goto err;
+ }
+
}
/*
* Compute shared IV and store it in algorithm-specific context data.
*/
- ukm_hash = EVP_MD_CTX_new();
- if (ukm_hash == NULL) {
- SSLerror(s, ERR_R_MALLOC_FAILURE);
+ if (!tls1_set_gost_ukm(s, pkey_ctx, psexp))
goto err;
- }
-
- if (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_GOST94)
- nid = NID_id_GostR3411_94;
- else
- nid = NID_id_tc26_gost3411_2012_256;
- if (!EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid)))
- goto err;
- EVP_DigestUpdate(ukm_hash, s->s3->client_random, SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(ukm_hash, s->s3->server_random, SSL3_RANDOM_SIZE);
- EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len);
- EVP_MD_CTX_free(ukm_hash);
- if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT,
- EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) {
- SSLerror(s, SSL_R_LIBRARY_BUG);
- goto err;
- }
/*
* Make GOST keytransport blob message, encapsulate it into sequence.
*/
- msglen = 255;
- if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret,
- 32) < 0) {
+ if (EVP_PKEY_encrypt(pkey_ctx, NULL, &msglen,
+ premaster_secret, sizeof(premaster_secret)) < 0) {
SSLerror(s, SSL_R_LIBRARY_BUG);
goto err;
}
-
- if (!CBB_add_asn1(cbb, &gostblob, CBS_ASN1_SEQUENCE))
- goto err;
- if (!CBB_add_bytes(&gostblob, tmp, msglen))
+ if ((tmp = malloc(msglen)) == NULL) {
+ SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
- if (!CBB_flush(cbb))
+ }
+ if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen,
+ premaster_secret, sizeof(premaster_secret)) < 0) {
+ SSLerror(s, SSL_R_LIBRARY_BUG);
goto err;
+ }
+
+ if (psexp) {
+ if (!CBB_add_bytes(cbb, tmp, msglen))
+ goto err;
+ if (!CBB_flush(cbb))
+ goto err;
+ } else {
+ CBB gostblob;
+
+ if (!CBB_add_asn1(cbb, &gostblob, CBS_ASN1_SEQUENCE))
+ goto err;
+ if (!CBB_add_bytes(&gostblob, tmp, msglen))
+ goto err;
+ if (!CBB_flush(cbb))
+ goto err;
+ }
/* Check if pubkey from client certificate was used. */
if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2,
@@ -2283,7 +2293,10 @@ ssl3_send_client_key_exchange(SSL *s)
if (ssl3_send_client_kex_ecdhe(s, sess_cert, &kex) != 1)
goto err;
} else if (alg_k & SSL_kGOST) {
- if (ssl3_send_client_kex_gost(s, sess_cert, &kex) != 1)
+ if (ssl3_send_client_kex_gost(s, sess_cert, &kex, 0) != 1)
+ goto err;
+ } else if (alg_k & SSL_kGOST_KDF) {
+ if (ssl3_send_client_kex_gost(s, sess_cert, &kex, 1) != 1)
goto err;
} else {
ssl3_send_alert(s, SSL3_AL_FATAL,
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index 6ef2083f5..5495a74ad 100644
--- a/src/lib/libssl/ssl_lib.c
+++ b/src/lib/libssl/ssl_lib.c
@@ -2000,7 +2000,7 @@ ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
cpk = &(c->pkeys[SSL_PKEY_GOST01]);
if (cpk->x509 != NULL && cpk->privatekey != NULL) {
- mask_k |= SSL_kGOST;
+ mask_k |= SSL_kGOST | SSL_kGOST_KDF;
mask_a |= SSL_aGOST01;
}
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 72646fa8c..b07be5ab2 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1373,6 +1373,8 @@ int ssl_check_serverhello_tlsext(SSL *s);
int tls1_process_ticket(SSL *s, CBS *session_id, CBS *ext_block,
SSL_SESSION **ret);
+int tls1_set_gost_ukm(SSL *s, EVP_PKEY_CTX *pkey_ctx, unsigned int psexp);
+
long ssl_get_algorithm2(SSL *s);
int tls1_check_ec_server_key(SSL *s);
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index 69e547cbe..1d924617c 100644
--- a/src/lib/libssl/ssl_srvr.c
+++ b/src/lib/libssl/ssl_srvr.c
@@ -1935,10 +1935,10 @@ ssl3_get_client_kex_ecdhe(SSL *s, CBS *cbs)
}
static int
-ssl3_get_client_kex_gost(SSL *s, CBS *cbs)
+ssl3_get_client_kex_gost(SSL *s, CBS *cbs, int psexp)
{
EVP_PKEY_CTX *pkey_ctx;
- EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
+ EVP_PKEY *pk = NULL;
unsigned char premaster_secret[32];
unsigned long alg_a;
size_t outlen = 32;
@@ -1954,56 +1954,83 @@ ssl3_get_client_kex_gost(SSL *s, CBS *cbs)
if ((pkey_ctx = EVP_PKEY_CTX_new(pk, NULL)) == NULL)
goto err;
if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0)
- goto gerr;
+ goto err;
- /*
- * If client certificate is present and is of the same type,
- * maybe use it for key exchange.
- * Don't mind errors from EVP_PKEY_derive_set_peer, because
- * it is completely valid to use a client certificate for
- * authorization only.
- */
- if ((client_pub_pkey = X509_get_pubkey(s->session->peer)) != NULL) {
- if (EVP_PKEY_derive_set_peer(pkey_ctx,
- client_pub_pkey) <= 0)
- ERR_clear_error();
+ if (!psexp) {
+ EVP_PKEY *client_pub_pkey = X509_get_pubkey(s->session->peer);
+ /*
+ * If client certificate is present and is of the same type,
+ * maybe use it for key exchange.
+ * Don't mind errors from EVP_PKEY_derive_set_peer, because
+ * it is completely valid to use a client certificate for
+ * authorization only.
+ */
+ if (client_pub_pkey != NULL) {
+ if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
+ ERR_clear_error();
+ EVP_PKEY_free(client_pub_pkey);
+ }
+
+ /*
+ * Compute shared IV and store it in algorithm-specific context data.
+ */
+ if (!tls1_set_gost_ukm(s, pkey_ctx, psexp))
+ goto err;
+
+ /* Decrypt session key */
+ if (!CBS_get_asn1(cbs, &gostblob, CBS_ASN1_SEQUENCE))
+ goto truncated;
+ } else {
+ int format;
+
+ if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_MAGMA_CTR_ACPKM)
+ format = GOST_ENC_FORMAT_PSKEY_MAGMA;
+ else
+ format = GOST_ENC_FORMAT_PSKEY_KUZNYECHIK;
+
+ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_DECRYPT,
+ EVP_PKEY_CTRL_GOST_ENC_FORMAT,
+ format, NULL) <= 0) {
+ SSLerror(s, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ /*
+ * Compute shared IV and store it in algorithm-specific context data.
+ */
+ if (!tls1_set_gost_ukm(s, pkey_ctx, psexp))
+ goto err;
+
+ /* Decrypt session key */
+ if (!CBS_get_asn1_element(cbs, &gostblob, CBS_ASN1_SEQUENCE))
+ goto truncated;
}
- /* Decrypt session key */
- if (!CBS_get_asn1(cbs, &gostblob, CBS_ASN1_SEQUENCE))
- goto truncated;
if (CBS_len(cbs) != 0)
goto truncated;
if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen,
- CBS_data(&gostblob), CBS_len(&gostblob)) <= 0) {
+ CBS_data(&gostblob), CBS_len(&gostblob)) <= 0 ||
+ outlen != 32) {
SSLerror(s, SSL_R_DECRYPTION_FAILED);
- goto gerr;
+ goto err;
}
/* Generate master secret */
s->session->master_key_length =
tls1_generate_master_secret(
- s, s->session->master_key, premaster_secret, 32);
+ s, s->session->master_key, premaster_secret, outlen);
- /* Check if pubkey from client certificate was used */
- if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1,
- EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
- ret = 2;
- else
- ret = 1;
- gerr:
- EVP_PKEY_free(client_pub_pkey);
+ ret = 1;
+
+err:
EVP_PKEY_CTX_free(pkey_ctx);
- if (ret)
- return (ret);
- else
- goto err;
+
+ return ret;
truncated:
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
ssl3_send_alert(s, SSL3_AL_FATAL, al);
- err:
return (-1);
}
@@ -2038,7 +2065,10 @@ ssl3_get_client_key_exchange(SSL *s)
if (ssl3_get_client_kex_ecdhe(s, &cbs) != 1)
goto err;
} else if (alg_k & SSL_kGOST) {
- if (ssl3_get_client_kex_gost(s, &cbs) != 1)
+ if (ssl3_get_client_kex_gost(s, &cbs, 0) != 1)
+ goto err;
+ } else if (alg_k & SSL_kGOST_KDF) {
+ if (ssl3_get_client_kex_gost(s, &cbs, 1) != 1)
goto err;
} else {
al = SSL_AD_HANDSHAKE_FAILURE;
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 580ae4b19..3da2ebb8c 100644
--- a/src/lib/libssl/t1_lib.c
+++ b/src/lib/libssl/t1_lib.c
@@ -1029,3 +1029,45 @@ tls_decrypt_ticket(SSL *s, CBS *session_id, CBS *ticket, SSL_SESSION **psess)
return ret;
}
+
+/*
+ * Compute shared IV and store it in algorithm-specific context data.
+ */
+int
+tls1_set_gost_ukm(SSL *s, EVP_PKEY_CTX *pkey_ctx, unsigned int psexp)
+{
+ unsigned char shared_ukm[32];
+ unsigned int md_len;
+ EVP_MD_CTX *ukm_hash;
+ int nid;
+
+ ukm_hash = EVP_MD_CTX_new();
+ if (ukm_hash == NULL) {
+ SSLerror(s, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_GOST94)
+ nid = NID_id_GostR3411_94;
+ else
+ nid = NID_id_tc26_gost3411_2012_256;
+ if (!EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid)) ||
+ !EVP_DigestUpdate(ukm_hash, s->s3->client_random, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestUpdate(ukm_hash, s->s3->server_random, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len)) {
+ SSLerror(s, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1,
+ EVP_PKEY_CTRL_SET_IV, psexp ? md_len : 8, shared_ukm) < 0) {
+ SSLerror(s, SSL_R_LIBRARY_BUG);
+ goto err;
+ }
+ EVP_MD_CTX_free(ukm_hash);
+ return 1;
+
+err:
+ EVP_MD_CTX_free(ukm_hash);
+ return 0;
+}
--
2.17.1

View file

@ -0,0 +1,158 @@
From d549ac36b23762900f5e07cc5afa41e1169141ac Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 17:21:43 +0300
Subject: [PATCH 79/87] ssl: support selecting CMAC for CTR-OMAC ciphersuites
CTR-OMAC ciphersuites use CMAC instead of HMAC to generate record MACs.
Make ssl_cipher_get_evp() return either MD (for HMAC) or a cipher (for
CMAC).
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/ssl_ciph.c | 20 ++++++++++++++++++--
src/lib/libssl/ssl_locl.h | 3 ++-
src/lib/libssl/t1_enc.c | 18 ++++++++++++++----
3 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c
index a3e0d396b..0f1995c20 100644
--- a/src/lib/libssl/ssl_ciph.c
+++ b/src/lib/libssl/ssl_ciph.c
@@ -448,10 +448,11 @@ static const SSL_CIPHER cipher_aliases[] = {
int
ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc,
- const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size)
+ const EVP_MD **md, const EVP_CIPHER **mac_ciph, int *mac_pkey_type, int *mac_secret_size)
{
*enc = NULL;
*md = NULL;
+ *mac_ciph = NULL;
*mac_pkey_type = NID_undef;
*mac_secret_size = 0;
@@ -490,6 +491,12 @@ ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc,
case SSL_eGOST2814789CNT:
*enc = EVP_gost2814789_cnt();
break;
+ case SSL_KUZNYECHIK_CTR_ACPKM:
+ *enc = EVP_kuznyechik_ctr_acpkm();
+ break;
+ case SSL_MAGMA_CTR_ACPKM:
+ *enc = EVP_magma_ctr_acpkm();
+ break;
}
switch (ss->cipher->algorithm_mac) {
@@ -514,9 +521,15 @@ ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc,
case SSL_STREEBOG256:
*md = EVP_streebog256();
break;
+ case SSL_MAGMA_OMAC:
+ *mac_ciph = EVP_magma_cbc();
+ break;
+ case SSL_KUZNYECHIK_OMAC:
+ *mac_ciph = EVP_kuznyechik_cbc();
+ break;
}
- if (*enc == NULL || *md == NULL)
+ if (*enc == NULL || (*md == NULL && *mac_ciph == NULL))
return 0;
/*
@@ -531,6 +544,9 @@ ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc,
if (ss->cipher->algorithm_mac == SSL_GOST89MAC) {
*mac_pkey_type = EVP_PKEY_GOSTIMIT;
*mac_secret_size = 32; /* XXX */
+ } else if (*mac_ciph) {
+ *mac_pkey_type = EVP_PKEY_CMAC;
+ *mac_secret_size = EVP_CIPHER_key_length(*mac_ciph);
} else {
*mac_pkey_type = EVP_PKEY_HMAC;
*mac_secret_size = EVP_MD_size(*md);
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index b07be5ab2..87eb05999 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -901,6 +901,7 @@ typedef struct ssl3_state_internal_st {
const EVP_CIPHER *new_sym_enc;
const EVP_AEAD *new_aead;
const EVP_MD *new_hash;
+ const EVP_CIPHER *new_hash_cipher;
int new_mac_pkey_type;
int cert_request;
} tmp;
@@ -1146,7 +1147,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
const char *rule_str);
void ssl_update_cache(SSL *s, int mode);
int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
- const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size);
+ const EVP_MD **md, const EVP_CIPHER **mac_ciph, int *mac_pkey_type, int *mac_secret_size);
int ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead);
int ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md);
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 2893e1d4d..736670259 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -408,10 +408,12 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
EVP_MD_CTX *mac_ctx;
EVP_PKEY *mac_key;
const EVP_MD *mac;
+ const EVP_CIPHER *mac_cipher;
int mac_type;
cipher = S3I(s)->tmp.new_sym_enc;
mac = S3I(s)->tmp.new_hash;
+ mac_cipher = S3I(s)->tmp.new_hash_cipher;
mac_type = S3I(s)->tmp.new_mac_pkey_type;
if (is_read) {
@@ -454,8 +456,14 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read);
- if ((mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,
- mac_secret_size)) == NULL)
+ if (mac_type == EVP_PKEY_CMAC) {
+ mac_key = EVP_PKEY_new_CMAC_key(NULL, mac_secret,
+ mac_secret_size, mac_cipher);
+ } else {
+ mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,
+ mac_secret_size);
+ }
+ if (mac_key == NULL)
goto err;
EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key);
EVP_PKEY_free(mac_key);
@@ -587,6 +595,7 @@ tls1_setup_key_block(SSL *s)
const EVP_CIPHER *cipher = NULL;
const EVP_AEAD *aead = NULL;
const EVP_MD *mac = NULL;
+ const EVP_CIPHER *mac_cipher = NULL;
int ret = 0;
if (S3I(s)->hs.key_block_len != 0)
@@ -601,8 +610,8 @@ tls1_setup_key_block(SSL *s)
key_len = EVP_AEAD_key_length(aead);
iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->session->cipher);
} else {
- if (!ssl_cipher_get_evp(s->session, &cipher, &mac, &mac_type,
- &mac_secret_size)) {
+ if (!ssl_cipher_get_evp(s->session, &cipher, &mac, &mac_cipher,
+ &mac_type, &mac_secret_size)) {
SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return (0);
}
@@ -613,6 +622,7 @@ tls1_setup_key_block(SSL *s)
S3I(s)->tmp.new_aead = aead;
S3I(s)->tmp.new_sym_enc = cipher;
S3I(s)->tmp.new_hash = mac;
+ S3I(s)->tmp.new_hash_cipher = mac_cipher;
S3I(s)->tmp.new_mac_pkey_type = mac_type;
S3I(s)->tmp.new_mac_secret_size = mac_secret_size;
--
2.17.1

View file

@ -0,0 +1,31 @@
From 85709a17e3cb44997455f5120f454a65a85b6678 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 17:31:59 +0300
Subject: [PATCH 80/87] ssl: select ACPKM session size for CTR-OMAC
ciphersuites
Set ACPKM session size for MAGMA and KUZNYECHIK CTR-ACPKM ciphers.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/t1_enc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 736670259..a3814dd44 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -478,6 +478,10 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GOST_SET_SBOX, nid, 0);
if (S3I(s)->hs.new_cipher->algorithm_mac == SSL_GOST89MAC)
EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_GOST_SET_SBOX, nid, 0);
+ } else if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_MAGMA_CTR_ACPKM) {
+ EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GOST_SET_MESHING, 1024, 0);
+ } else if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_KUZNYECHIK_CTR_ACPKM) {
+ EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GOST_SET_MESHING, 4096, 0);
}
return (1);
--
2.17.1

View file

@ -0,0 +1,150 @@
From 55d3c8d25a6bd5764dcafed8b899723b80fd5a92 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 19:05:59 +0300
Subject: [PATCH 81/87] ssl: fix Finished message length for CTR-OMAC
ciphersuites
CTR-OMAC ciphersuites use 32-byte Finished messages. Generate them
properly.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/ssl_both.c | 18 ++++++++++--------
src/lib/libssl/ssl_locl.h | 5 +++--
src/lib/libssl/ssl_pkt.c | 2 +-
src/lib/libssl/t1_enc.c | 13 ++++++++++---
4 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/src/lib/libssl/ssl_both.c b/src/lib/libssl/ssl_both.c
index 488a5ff7c..8c71e580f 100644
--- a/src/lib/libssl/ssl_both.c
+++ b/src/lib/libssl/ssl_both.c
@@ -175,9 +175,12 @@ ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
md_len = TLS1_FINISH_MAC_LENGTH;
OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
- if (tls1_final_finish_mac(s, sender, slen,
- S3I(s)->tmp.finish_md) != md_len)
+ md_len = tls1_final_finish_mac(s, sender, slen,
+ S3I(s)->tmp.finish_md, sizeof(S3I(s)->tmp.finish_md));
+ if (md_len == 0) {
+ SSLerror(s, ERR_R_INTERNAL_ERROR);
return (0);
+ }
S3I(s)->tmp.finish_md_len = md_len;
/* Copy finished so we can use it for renegotiation checks. */
@@ -237,7 +240,7 @@ ssl3_take_mac(SSL *s)
S3I(s)->tmp.peer_finish_md_len =
tls1_final_finish_mac(s, sender, slen,
- S3I(s)->tmp.peer_finish_md);
+ S3I(s)->tmp.peer_finish_md, sizeof(S3I(s)->tmp.peer_finish_md));
}
int
@@ -260,8 +263,6 @@ ssl3_get_finished(SSL *s, int a, int b)
}
S3I(s)->change_cipher_spec = 0;
- md_len = TLS1_FINISH_MAC_LENGTH;
-
if (n < 0) {
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
@@ -270,14 +271,15 @@ ssl3_get_finished(SSL *s, int a, int b)
CBS_init(&cbs, s->internal->init_msg, n);
- if (S3I(s)->tmp.peer_finish_md_len != md_len ||
- CBS_len(&cbs) != md_len) {
+ md_len = S3I(s)->tmp.peer_finish_md_len;
+
+ if (CBS_len(&cbs) != md_len) {
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
goto f_err;
}
- if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, CBS_len(&cbs))) {
+ if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, md_len)) {
al = SSL_AD_DECRYPT_ERROR;
SSLerror(s, SSL_R_DIGEST_CHECK_FAILED);
goto f_err;
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 87eb05999..f522abf96 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -874,7 +874,8 @@ typedef struct ssl3_state_internal_st {
/* actually only needs to be 16+20 */
unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
- /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+ /* actually only need to be 16+20 for SSLv3 and 12 for TLS
+ * 32 for GOST CTR-OMAC ciphersuites */
unsigned char finish_md[EVP_MAX_MD_SIZE*2];
int finish_md_len;
unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
@@ -1337,7 +1338,7 @@ void tls1_cleanup_key_block(SSL *s);
int tls1_change_cipher_state(SSL *s, int which);
int tls1_setup_key_block(SSL *s);
int tls1_enc(SSL *s, int snd);
-int tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *p);
+int tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out, unsigned int outlen);
int tls1_mac(SSL *ssl, unsigned char *md, int snd);
int tls1_generate_master_secret(SSL *s, unsigned char *out,
unsigned char *p, int len);
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index 157dd9895..d4aebebe9 100644
--- a/src/lib/libssl/ssl_pkt.c
+++ b/src/lib/libssl/ssl_pkt.c
@@ -1388,7 +1388,7 @@ ssl3_do_change_cipher_spec(SSL *s)
}
i = tls1_final_finish_mac(s, sender, slen,
- S3I(s)->tmp.peer_finish_md);
+ S3I(s)->tmp.peer_finish_md, sizeof(S3I(s)->tmp.peer_finish_md));
if (i == 0) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
return 0;
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index a3814dd44..7e9422b51 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -926,23 +926,30 @@ tls1_enc(SSL *s, int send)
}
int
-tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out)
+tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out, unsigned int outlen)
{
unsigned char buf[EVP_MAX_MD_SIZE];
size_t hash_len;
+ int finished_len = TLS1_FINISH_MAC_LENGTH;
if (str_len < 0)
return 0;
+ if (S3I(s)->hs.new_cipher->algorithm_mkey == SSL_kGOST_KDF)
+ finished_len = 32;
+
+ if (finished_len > outlen)
+ return 0;
+
if (!tls1_transcript_hash_value(s, buf, sizeof(buf), &hash_len))
return 0;
if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length,
str, str_len, buf, hash_len, NULL, 0, NULL, 0, NULL, 0,
- out, TLS1_FINISH_MAC_LENGTH))
+ out, finished_len))
return 0;
- return TLS1_FINISH_MAC_LENGTH;
+ return finished_len;
}
int
--
2.17.1

View file

@ -0,0 +1,182 @@
From a5ef2b157731e3bd2f9c0dbba4caf361195fa5c8 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 22:43:37 +0300
Subject: [PATCH 82/87] ssl: fix CMAC support
For CMAC EVP_MD_CTX_md is NULL. Thus tls1_mac() will not be called.
Store read/write mac_size in the context to make it work.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/ssl.h | 1 +
src/lib/libssl/ssl_lib.c | 2 ++
src/lib/libssl/ssl_locl.h | 1 +
src/lib/libssl/ssl_pkt.c | 11 ++++-------
src/lib/libssl/t1_enc.c | 23 ++++++++++++-----------
5 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index b11216b1e..1f9095feb 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -872,6 +872,7 @@ struct ssl_st {
*/
EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
EVP_MD_CTX *read_hash; /* used for mac generation */
+ int read_mac_size;
struct ssl_internal_st *internal;
};
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index 5495a74ad..c989d802c 100644
--- a/src/lib/libssl/ssl_lib.c
+++ b/src/lib/libssl/ssl_lib.c
@@ -2538,6 +2538,7 @@ ssl_clear_cipher_read_state(SSL *s)
s->enc_read_ctx = NULL;
EVP_MD_CTX_free(s->read_hash);
s->read_hash = NULL;
+ s->read_mac_size = 0;
if (s->internal->aead_read_ctx != NULL) {
EVP_AEAD_CTX_cleanup(&s->internal->aead_read_ctx->ctx);
@@ -2553,6 +2554,7 @@ ssl_clear_cipher_write_state(SSL *s)
s->internal->enc_write_ctx = NULL;
EVP_MD_CTX_free(s->internal->write_hash);
s->internal->write_hash = NULL;
+ s->internal->write_mac_size = 0;
if (s->internal->aead_write_ctx != NULL) {
EVP_AEAD_CTX_cleanup(&s->internal->aead_write_ctx->ctx);
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index f522abf96..858010b87 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -737,6 +737,7 @@ typedef struct ssl_internal_st {
EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
EVP_MD_CTX *write_hash; /* used for mac generation */
+ int write_mac_size;
/* session info */
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index d4aebebe9..23a5509c3 100644
--- a/src/lib/libssl/ssl_pkt.c
+++ b/src/lib/libssl/ssl_pkt.c
@@ -443,12 +443,12 @@ ssl3_get_record(SSL *s)
/* r->length is now the compressed data plus mac */
if ((sess != NULL) && (s->enc_read_ctx != NULL) &&
- (EVP_MD_CTX_md(s->read_hash) != NULL)) {
+ (s->read_mac_size != 0)) {
/* s->read_hash != NULL => mac_size != -1 */
unsigned char *mac = NULL;
unsigned char mac_tmp[EVP_MAX_MD_SIZE];
- mac_size = EVP_MD_CTX_size(s->read_hash);
+ mac_size = s->read_mac_size;
OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
orig_len = rr->length + rr->padding_length;
@@ -628,13 +628,10 @@ ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf,
memset(&cbb, 0, sizeof(cbb));
- if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) ||
- (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) {
+ if ((sess == NULL) || (s->internal->enc_write_ctx == NULL)) {
mac_size = 0;
} else {
- mac_size = EVP_MD_CTX_size(s->internal->write_hash);
- if (mac_size < 0)
- goto err;
+ mac_size = s->internal->write_mac_size;
}
/*
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 7e9422b51..363447b52 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -407,6 +407,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
const EVP_CIPHER *cipher;
EVP_MD_CTX *mac_ctx;
EVP_PKEY *mac_key;
+ int mac_size;
const EVP_MD *mac;
const EVP_CIPHER *mac_cipher;
int mac_type;
@@ -459,14 +460,20 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
if (mac_type == EVP_PKEY_CMAC) {
mac_key = EVP_PKEY_new_CMAC_key(NULL, mac_secret,
mac_secret_size, mac_cipher);
+ mac_size = EVP_CIPHER_block_size(mac_cipher);
} else {
mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,
mac_secret_size);
+ mac_size = EVP_MD_size(mac);
}
if (mac_key == NULL)
goto err;
EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key);
EVP_PKEY_free(mac_key);
+ if (is_read)
+ s->read_mac_size = mac_size;
+ else
+ s->internal->write_mac_size = mac_size;
if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) {
int nid;
@@ -846,10 +853,7 @@ tls1_enc(SSL *s, int send)
}
if (send) {
- if (EVP_MD_CTX_md(s->internal->write_hash)) {
- int n = EVP_MD_CTX_size(s->internal->write_hash);
- OPENSSL_assert(n >= 0);
- }
+ OPENSSL_assert(s->internal->write_mac_size >= 0);
ds = s->internal->enc_write_ctx;
if (s->internal->enc_write_ctx == NULL)
enc = NULL;
@@ -874,10 +878,7 @@ tls1_enc(SSL *s, int send)
}
}
} else {
- if (EVP_MD_CTX_md(s->read_hash)) {
- int n = EVP_MD_CTX_size(s->read_hash);
- OPENSSL_assert(n >= 0);
- }
+ OPENSSL_assert(s->read_mac_size >= 0);
ds = s->enc_read_ctx;
if (s->enc_read_ctx == NULL)
enc = NULL;
@@ -917,8 +918,7 @@ tls1_enc(SSL *s, int send)
return -1; /* AEAD can fail to verify MAC */
ret = 1;
- if (EVP_MD_CTX_md(s->read_hash) != NULL)
- mac_size = EVP_MD_CTX_size(s->read_hash);
+ mac_size = s->read_mac_size;
if ((bs != 1) && !send)
ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
}
@@ -970,13 +970,14 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
rec = &(ssl->s3->internal->wrec);
seq = &(ssl->s3->internal->write_sequence[0]);
hash = ssl->internal->write_hash;
+ t = ssl->internal->write_mac_size;
} else {
rec = &(ssl->s3->internal->rrec);
seq = &(ssl->s3->internal->read_sequence[0]);
hash = ssl->read_hash;
+ t = ssl->read_mac_size;
}
- t = EVP_MD_CTX_size(hash);
OPENSSL_assert(t >= 0);
md_size = t;
--
2.17.1

View file

@ -0,0 +1,261 @@
From c9bfbd055ab424bf13a4790d2321f6dc32aac555 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 15 Apr 2020 23:53:16 +0300
Subject: [PATCH 83/87] ssl: merge read and write sequence/secrets into common
state
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/d1_both.c | 16 ++++++++--------
src/lib/libssl/d1_pkt.c | 22 +++++++++++-----------
src/lib/libssl/ssl_locl.h | 14 ++++++++------
src/lib/libssl/ssl_srvr.c | 6 +++---
src/lib/libssl/t1_enc.c | 25 +++++++++++--------------
5 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c
index 8f3cc610b..4859bdea2 100644
--- a/src/lib/libssl/d1_both.c
+++ b/src/lib/libssl/d1_both.c
@@ -1084,10 +1084,10 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
if (frag->msg_header.saved_retransmit_state.epoch ==
saved_state.epoch - 1) {
- memcpy(save_write_sequence, S3I(s)->write_sequence,
- sizeof(S3I(s)->write_sequence));
- memcpy(S3I(s)->write_sequence, D1I(s)->last_write_sequence,
- sizeof(S3I(s)->write_sequence));
+ memcpy(save_write_sequence, S3I(s)->write.sequence,
+ sizeof(S3I(s)->write.sequence));
+ memcpy(S3I(s)->write.sequence, D1I(s)->last_write_sequence,
+ sizeof(S3I(s)->write.sequence));
}
ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
@@ -1101,10 +1101,10 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
if (frag->msg_header.saved_retransmit_state.epoch ==
saved_state.epoch - 1) {
- memcpy(D1I(s)->last_write_sequence, S3I(s)->write_sequence,
- sizeof(S3I(s)->write_sequence));
- memcpy(S3I(s)->write_sequence, save_write_sequence,
- sizeof(S3I(s)->write_sequence));
+ memcpy(D1I(s)->last_write_sequence, S3I(s)->write.sequence,
+ sizeof(S3I(s)->write.sequence));
+ memcpy(S3I(s)->write.sequence, save_write_sequence,
+ sizeof(S3I(s)->write.sequence));
}
D1I(s)->retransmitting = 0;
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c
index 36090533a..8c18bcdb8 100644
--- a/src/lib/libssl/d1_pkt.c
+++ b/src/lib/libssl/d1_pkt.c
@@ -208,7 +208,7 @@ dtls1_copy_record(SSL *s, pitem *item)
memcpy(&(S3I(s)->rrec), &(rdata->rrec), sizeof(SSL3_RECORD_INTERNAL));
/* Set proper sequence number for mac calculation */
- memcpy(&(S3I(s)->read_sequence[2]), &(rdata->packet[5]), 6);
+ memcpy(&(S3I(s)->read.sequence[2]), &(rdata->packet[5]), 6);
return (1);
}
@@ -520,8 +520,8 @@ again:
!CBS_get_bytes(&header, &seq_no, 6))
goto again;
- if (!CBS_write_bytes(&seq_no, &(S3I(s)->read_sequence[2]),
- sizeof(S3I(s)->read_sequence) - 2, NULL))
+ if (!CBS_write_bytes(&seq_no, &(S3I(s)->read.sequence[2]),
+ sizeof(S3I(s)->read.sequence) - 2, NULL))
goto again;
if (!CBS_get_u16(&header, &len))
goto again;
@@ -1232,7 +1232,7 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
goto err;
if (!CBB_add_u16(&cbb, D1I(s)->w_epoch))
goto err;
- if (!CBB_add_bytes(&cbb, &(S3I(s)->write_sequence[2]), 6))
+ if (!CBB_add_bytes(&cbb, &(S3I(s)->write.sequence[2]), 6))
goto err;
p += DTLS1_RT_HEADER_LENGTH;
@@ -1296,7 +1296,7 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
wr->type = type; /* not needed but helps for debugging */
wr->length += DTLS1_RT_HEADER_LENGTH;
- tls1_record_sequence_increment(S3I(s)->write_sequence);
+ tls1_record_sequence_increment(S3I(s)->write.sequence);
/* now let's set up wb */
wb->left = wr->length;
@@ -1324,7 +1324,7 @@ dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
{
int cmp;
unsigned int shift;
- const unsigned char *seq = S3I(s)->read_sequence;
+ const unsigned char *seq = S3I(s)->read.sequence;
cmp = satsub64be(seq, bitmap->max_seq_num);
if (cmp > 0) {
@@ -1347,7 +1347,7 @@ dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
{
int cmp;
unsigned int shift;
- const unsigned char *seq = S3I(s)->read_sequence;
+ const unsigned char *seq = S3I(s)->read.sequence;
cmp = satsub64be(seq, bitmap->max_seq_num);
if (cmp > 0) {
@@ -1429,16 +1429,16 @@ void
dtls1_reset_seq_numbers(SSL *s, int rw)
{
unsigned char *seq;
- unsigned int seq_bytes = sizeof(S3I(s)->read_sequence);
+ unsigned int seq_bytes = sizeof(S3I(s)->read.sequence);
if (rw & SSL3_CC_READ) {
- seq = S3I(s)->read_sequence;
+ seq = S3I(s)->read.sequence;
D1I(s)->r_epoch++;
memcpy(&(D1I(s)->bitmap), &(D1I(s)->next_bitmap), sizeof(DTLS1_BITMAP));
memset(&(D1I(s)->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
} else {
- seq = S3I(s)->write_sequence;
- memcpy(D1I(s)->last_write_sequence, seq, sizeof(S3I(s)->write_sequence));
+ seq = S3I(s)->write.sequence;
+ memcpy(D1I(s)->last_write_sequence, seq, sizeof(S3I(s)->write.sequence));
D1I(s)->w_epoch++;
}
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 858010b87..2ef7e58f6 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -808,13 +808,15 @@ typedef struct ssl3_buffer_internal_st {
int left; /* how many bytes left */
} SSL3_BUFFER_INTERNAL;
+typedef struct ssl3_rw_state_internal_st {
+ unsigned char sequence[SSL3_SEQUENCE_SIZE];
+ int mac_secret_size;
+ unsigned char mac_secret[EVP_MAX_MD_SIZE];
+} SSL3_RW_STATE_INTERNAL;
+
typedef struct ssl3_state_internal_st {
- unsigned char read_sequence[SSL3_SEQUENCE_SIZE];
- int read_mac_secret_size;
- unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
- unsigned char write_sequence[SSL3_SEQUENCE_SIZE];
- int write_mac_secret_size;
- unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
+ SSL3_RW_STATE_INTERNAL read;
+ SSL3_RW_STATE_INTERNAL write;
SSL3_BUFFER_INTERNAL rbuf; /* read IO goes into here */
SSL3_BUFFER_INTERNAL wbuf; /* write IO goes into here */
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index 1d924617c..e620a563d 100644
--- a/src/lib/libssl/ssl_srvr.c
+++ b/src/lib/libssl/ssl_srvr.c
@@ -328,9 +328,9 @@ ssl3_accept(SSL *s)
* stateless while listening.
*/
if (listen) {
- memcpy(S3I(s)->write_sequence,
- S3I(s)->read_sequence,
- sizeof(S3I(s)->write_sequence));
+ memcpy(S3I(s)->write.sequence,
+ S3I(s)->read.sequence,
+ sizeof(S3I(s)->write.sequence));
}
/* If we're just listening, stop here */
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 363447b52..05c45fc31 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -510,6 +510,7 @@ tls1_change_cipher_state(SSL *s, int which)
const EVP_CIPHER *cipher;
const EVP_AEAD *aead;
char is_read, use_client_keys;
+ SSL3_RW_STATE_INTERNAL *rws;
cipher = S3I(s)->tmp.new_sym_enc;
aead = S3I(s)->tmp.new_aead;
@@ -520,6 +521,7 @@ tls1_change_cipher_state(SSL *s, int which)
* just written one.
*/
is_read = (which & SSL3_CC_READ) != 0;
+ rws = is_read ? &S3I(s)->read : &S3I(s)->write;
/*
* use_client_keys is true if we wish to use the keys for the "client
@@ -534,7 +536,7 @@ tls1_change_cipher_state(SSL *s, int which)
* dtls1_reset_seq_numbers().
*/
if (!SSL_IS_DTLS(s)) {
- seq = is_read ? S3I(s)->read_sequence : S3I(s)->write_sequence;
+ seq = rws->sequence;
memset(seq, 0, SSL3_SEQUENCE_SIZE);
}
@@ -577,13 +579,8 @@ tls1_change_cipher_state(SSL *s, int which)
goto err2;
}
- if (is_read) {
- memcpy(S3I(s)->read_mac_secret, mac_secret, mac_secret_size);
- S3I(s)->read_mac_secret_size = mac_secret_size;
- } else {
- memcpy(S3I(s)->write_mac_secret, mac_secret, mac_secret_size);
- S3I(s)->write_mac_secret_size = mac_secret_size;
- }
+ memcpy(rws->mac_secret, mac_secret, mac_secret_size);
+ rws->mac_secret_size = mac_secret_size;
if (aead != NULL) {
return tls1_change_cipher_state_aead(s, is_read, key, key_len,
@@ -700,11 +697,11 @@ tls1_enc(SSL *s, int send)
if (send) {
aead = s->internal->aead_write_ctx;
rec = &S3I(s)->wrec;
- seq = S3I(s)->write_sequence;
+ seq = S3I(s)->write.sequence;
} else {
aead = s->internal->aead_read_ctx;
rec = &S3I(s)->rrec;
- seq = S3I(s)->read_sequence;
+ seq = S3I(s)->read.sequence;
}
if (aead) {
@@ -968,12 +965,12 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
if (send) {
rec = &(ssl->s3->internal->wrec);
- seq = &(ssl->s3->internal->write_sequence[0]);
+ seq = &(ssl->s3->internal->write.sequence[0]);
hash = ssl->internal->write_hash;
t = ssl->internal->write_mac_size;
} else {
rec = &(ssl->s3->internal->rrec);
- seq = &(ssl->s3->internal->read_sequence[0]);
+ seq = &(ssl->s3->internal->read.sequence[0]);
hash = ssl->read_hash;
t = ssl->read_mac_size;
}
@@ -1014,8 +1011,8 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
if (!ssl3_cbc_digest_record(mac_ctx,
md, &md_size, header, rec->input,
rec->length + md_size, orig_len,
- ssl->s3->internal->read_mac_secret,
- ssl->s3->internal->read_mac_secret_size))
+ ssl->s3->internal->read.mac_secret,
+ ssl->s3->internal->read.mac_secret_size))
return -1;
} else {
EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
--
2.17.1

View file

@ -0,0 +1,87 @@
From 1b42f56675b39ba4f1514b328a8dfb6c35b8cb4a Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 17 Apr 2020 16:43:39 +0300
Subject: [PATCH 84/87] ssl: drop mac_flags field
Use s->session->cipher->algorithm2 instead.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/ssl.h | 3 ---
src/lib/libssl/ssl_locl.h | 4 ----
src/lib/libssl/t1_enc.c | 16 +++-------------
3 files changed, 3 insertions(+), 20 deletions(-)
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index 1f9095feb..1c5e174b8 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -796,9 +796,6 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
-#define SSL_MAC_FLAG_READ_MAC_STREAM 1
-#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
-
#ifndef OPENSSL_NO_SSL_INTERN
struct ssl_internal_st;
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 2ef7e58f6..f4ad6b5ee 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -723,10 +723,6 @@ typedef struct ssl_internal_st {
/* crypto */
STACK_OF(SSL_CIPHER) *cipher_list_by_id;
- /* These are the ones being used, the ones in SSL_SESSION are
- * the ones to be 'copied' into these ones */
- int mac_flags;
-
SSL_AEAD_CTX *aead_read_ctx; /* AEAD context. If non-NULL, then
enc_read_ctx and read_hash are
ignored. */
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 05c45fc31..4c726f73f 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -418,11 +418,6 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
mac_type = S3I(s)->tmp.new_mac_pkey_type;
if (is_read) {
- if (S3I(s)->hs.new_cipher->algorithm2 & TLS1_STREAM_MAC)
- s->internal->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
- else
- s->internal->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
-
ssl_clear_cipher_read_state(s);
if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL)
@@ -432,11 +427,6 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
goto err;
s->read_hash = mac_ctx;
} else {
- if (S3I(s)->hs.new_cipher->algorithm2 & TLS1_STREAM_MAC)
- s->internal->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
- else
- s->internal->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
-
/*
* DTLS fragments retain a pointer to the compression, cipher
* and hash contexts, so that it can restore state in order
@@ -958,9 +948,9 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
size_t md_size, orig_len;
EVP_MD_CTX hmac, *mac_ctx;
unsigned char header[13];
- int stream_mac = (send ?
- (ssl->internal->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) :
- (ssl->internal->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));
+ int stream_mac = ssl->session && ssl->session->cipher ?
+ ssl->session->cipher->algorithm2 & TLS1_STREAM_MAC :
+ 0;
int t;
if (send) {
--
2.17.1

View file

@ -0,0 +1,177 @@
From a7c432fd088bbf6bc256fe96236c8e0a01322de5 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Fri, 17 Apr 2020 23:14:53 +0300
Subject: [PATCH 85/87] ssl: support IV increments for GOST CTR-OMAC
ciphersuites
CTR-OMAC ciphersuites are defined so that for each record cipher IV is
set to the one generated by key_block incremented by record's sequece
number. Support handling this in the encryption layer.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/s3_lib.c | 4 ++--
src/lib/libssl/ssl_locl.h | 3 +++
src/lib/libssl/ssl_pkt.c | 7 +++++++
src/lib/libssl/t1_enc.c | 38 +++++++++++++++++++++++++++++---------
4 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index 106a2567a..ba87e9101 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1316,7 +1316,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_KUZNYECHIK_OMAC,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256|TLS1_NONCE_ADD_SEQUENCE,
.strength_bits = 256,
.alg_bits = 256
},
@@ -1332,7 +1332,7 @@ SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_MAGMA_OMAC,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256|TLS1_NONCE_ADD_SEQUENCE,
.strength_bits = 256,
.alg_bits = 256
},
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index f4ad6b5ee..dc291ae4f 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -288,6 +288,7 @@ __BEGIN_HIDDEN_DECLS
* (currently this also goes into algorithm2).
*/
#define TLS1_STREAM_MAC 0x04
+#define TLS1_NONCE_ADD_SEQUENCE 0x02
/*
* SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD is an algorithm2 flag that
@@ -808,6 +809,8 @@ typedef struct ssl3_rw_state_internal_st {
unsigned char sequence[SSL3_SEQUENCE_SIZE];
int mac_secret_size;
unsigned char mac_secret[EVP_MAX_MD_SIZE];
+ int cipher_iv_size;
+ unsigned char cipher_iv[EVP_MAX_IV_LENGTH];
} SSL3_RW_STATE_INTERNAL;
typedef struct ssl3_state_internal_st {
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index 23a5509c3..e1cb249df 100644
--- a/src/lib/libssl/ssl_pkt.c
+++ b/src/lib/libssl/ssl_pkt.c
@@ -485,6 +485,7 @@ ssl3_get_record(SSL *s)
}
i = tls1_mac(s,md,0 /* not send */);
+ tls1_record_sequence_increment(S3I(s)->read.sequence);
if (i < 0 || mac == NULL ||
timingsafe_memcmp(md, mac, (size_t)mac_size) != 0)
enc_err = -1;
@@ -702,6 +703,12 @@ ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf,
/* tls1_enc can only have an error on read */
tls1_enc(s, 1);
+ /* Increment sequence after encrypting so that tls1_enc can use seq for
+ * nonce calculation */
+ if (mac_size != 0) {
+ tls1_record_sequence_increment(S3I(s)->write.sequence);
+ }
+
/* record length after mac and block padding */
if (!CBB_add_u16(&cbb, wr->length))
goto err;
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 4c726f73f..7ed6825a1 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -571,6 +571,8 @@ tls1_change_cipher_state(SSL *s, int which)
memcpy(rws->mac_secret, mac_secret, mac_secret_size);
rws->mac_secret_size = mac_secret_size;
+ memcpy(rws->cipher_iv, iv, iv_len);
+ rws->cipher_iv_size = iv_len;
if (aead != NULL) {
return tls1_change_cipher_state_aead(s, is_read, key, key_len,
@@ -680,18 +682,21 @@ tls1_enc(SSL *s, int send)
const EVP_CIPHER *enc;
EVP_CIPHER_CTX *ds;
SSL3_RECORD_INTERNAL *rec;
- unsigned char *seq;
+ SSL3_RW_STATE_INTERNAL *rws;
unsigned long l;
int bs, i, j, k, ret, mac_size = 0;
+ int add_nonce = s->session && s->session->cipher ?
+ s->session->cipher->algorithm2 & TLS1_NONCE_ADD_SEQUENCE:
+ 0;
if (send) {
aead = s->internal->aead_write_ctx;
rec = &S3I(s)->wrec;
- seq = S3I(s)->write.sequence;
+ rws = &S3I(s)->write;
} else {
aead = s->internal->aead_read_ctx;
rec = &S3I(s)->rrec;
- seq = S3I(s)->read.sequence;
+ rws = &S3I(s)->read;
}
if (aead) {
@@ -700,11 +705,11 @@ tls1_enc(SSL *s, int send)
unsigned int nonce_used;
if (SSL_IS_DTLS(s)) {
- dtls1_build_sequence_number(ad, seq,
+ dtls1_build_sequence_number(ad, rws->sequence,
send ? D1I(s)->w_epoch : D1I(s)->r_epoch);
} else {
- memcpy(ad, seq, SSL3_SEQUENCE_SIZE);
- tls1_record_sequence_increment(seq);
+ memcpy(ad, rws->sequence, SSL3_SEQUENCE_SIZE);
+ tls1_record_sequence_increment(rws->sequence);
}
ad[8] = rec->type;
@@ -899,6 +904,24 @@ tls1_enc(SSL *s, int send)
return 0;
}
+ if (add_nonce) {
+ unsigned char new_iv[EVP_MAX_IV_LENGTH];
+ int iv_size = rws->cipher_iv_size;
+ unsigned char cf = 0, tmp;
+
+ for (i = 1; i <= iv_size; i++) {
+ tmp = new_iv[iv_size - i] =
+ rws->cipher_iv[iv_size - i] + rws->sequence[SSL3_SEQUENCE_SIZE - i] + cf;
+ if (tmp != rws->cipher_iv[iv_size - i])
+ cf = (tmp < rws->cipher_iv[iv_size - i]);
+ }
+
+ if (!EVP_CipherInit_ex(ds, NULL, NULL, NULL, new_iv, -1)) {
+ SSLerror(s, ERR_R_EVP_LIB);
+ return -1;
+ }
+ }
+
i = EVP_Cipher(ds, rec->data, rec->input, l);
if ((EVP_CIPHER_flags(ds->cipher) &
EVP_CIPH_FLAG_CUSTOM_CIPHER) ? (i < 0) : (i == 0))
@@ -1014,9 +1037,6 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
if (!stream_mac)
EVP_MD_CTX_cleanup(&hmac);
- if (!SSL_IS_DTLS(ssl))
- tls1_record_sequence_increment(seq);
-
return (md_size);
}
--
2.17.1

View file

@ -0,0 +1,275 @@
From 363239bfbe92bfe654c21f1b181531ebdd8fa8ad Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sat, 18 Apr 2020 18:34:28 +0300
Subject: [PATCH 86/87] kdftree: add support for TLSTREE rekeying algorithm
GOST CTR-OMAC ciphersuites use external rekeying names TLSTREE. Add
support for this transformation.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libcrypto/kdftree/kdftree.c | 3 +-
src/lib/libcrypto/kdftree/kdftree.h | 23 ++++
src/lib/libcrypto/kdftree/kdftree_locl.h | 31 +++++
src/lib/libcrypto/kdftree/tlstree.c | 154 +++++++++++++++++++++++
4 files changed, 210 insertions(+), 1 deletion(-)
create mode 100644 src/lib/libcrypto/kdftree/kdftree_locl.h
create mode 100644 src/lib/libcrypto/kdftree/tlstree.c
diff --git a/src/lib/libcrypto/kdftree/kdftree.c b/src/lib/libcrypto/kdftree/kdftree.c
index 4dc7b0096..957ca2875 100644
--- a/src/lib/libcrypto/kdftree/kdftree.c
+++ b/src/lib/libcrypto/kdftree/kdftree.c
@@ -18,6 +18,7 @@
#include <openssl/kdftree.h>
#include <openssl/hmac.h>
+#include "kdftree_locl.h"
#include <string.h>
@@ -26,7 +27,7 @@
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
-static int
+int
kdf_tree_block(HMAC_CTX *ctx,
const unsigned char *i, unsigned int i_length,
const unsigned char *label, unsigned int label_length,
diff --git a/src/lib/libcrypto/kdftree/kdftree.h b/src/lib/libcrypto/kdftree/kdftree.h
index 132f70690..378b06b51 100644
--- a/src/lib/libcrypto/kdftree/kdftree.h
+++ b/src/lib/libcrypto/kdftree/kdftree.h
@@ -40,6 +40,29 @@ int KDF_TREE_SIMPLE(const EVP_MD *md, ENGINE *impl,
const unsigned char *seed, unsigned int seed_length,
unsigned char *out);
+/* TLSTREE is an external re-keying function (see
+ * draft-smyshlyaev-tls12-gost-suites Section 8 for the definition, RFC 8645
+ * Section 5.2.2 for the discussion of the approach. */
+
+/* Opaque */
+typedef struct TLSTREE_CTX_st TLSTREE_CTX;
+
+typedef struct tlstree_const_st {
+ uint64_t c1, c2, c3;
+} TLSTREE_CONST;
+
+TLSTREE_CTX *TLSTREE_CTX_new(void);
+void TLSTREE_CTX_free(TLSTREE_CTX *ctx);
+
+int TLSTREE_Init(TLSTREE_CTX *ctx,
+ const TLSTREE_CONST *tlsconst,
+ const EVP_MD *md, ENGINE *impl,
+ const unsigned char *key,
+ int key_length);
+int TLSTREE_GET(TLSTREE_CTX *ctx,
+ unsigned char *seq,
+ unsigned char *out);
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/lib/libcrypto/kdftree/kdftree_locl.h b/src/lib/libcrypto/kdftree/kdftree_locl.h
new file mode 100644
index 000000000..0eff3156d
--- /dev/null
+++ b/src/lib/libcrypto/kdftree/kdftree_locl.h
@@ -0,0 +1,31 @@
+/* $OpenBSD: kdftree_locl.h,v 1.4 2019/11/21 20:02:20 tim 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.
+ */
+
+#ifndef OPENSSL_HEADER_KDFTREE_LOCL_H
+#define OPENSSL_HEADER_KDFTREE_LOCL_H
+
+#include <openssl/hmac.h>
+
+int kdf_tree_block(HMAC_CTX *ctx,
+ const unsigned char *i, unsigned int i_length,
+ const unsigned char *label, unsigned int label_length,
+ const unsigned char *seed, unsigned int seed_length,
+ const unsigned char *l, unsigned int l_length,
+ unsigned char *out, unsigned int *length);
+
+#endif /* OPENSSL_HEADER_KDFTREE_LOCL_H */
diff --git a/src/lib/libcrypto/kdftree/tlstree.c b/src/lib/libcrypto/kdftree/tlstree.c
new file mode 100644
index 000000000..5c3322675
--- /dev/null
+++ b/src/lib/libcrypto/kdftree/tlstree.c
@@ -0,0 +1,154 @@
+/* $OpenBSD: tlstree.h,v 1.4 2019/11/21 20:02:20 tim 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 <openssl/kdftree.h>
+#include "kdftree_locl.h"
+#include <string.h>
+
+#define ll2c(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>48)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>40)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+#define c2ll(c,l) (l =((uint64_t)(*((c)++))) , \
+ l|=((uint64_t)(*((c)++)))<< 8, \
+ l|=((uint64_t)(*((c)++)))<<16, \
+ l|=((uint64_t)(*((c)++)))<<24, \
+ l|=((uint64_t)(*((c)++)))<<32, \
+ l|=((uint64_t)(*((c)++)))<<40, \
+ l|=((uint64_t)(*((c)++)))<<48, \
+ l|=((uint64_t)(*((c)++)))<<56)
+
+#define TLSTREE_L1 ((const unsigned char *)"level1")
+#define TLSTREE_L2 ((const unsigned char *)"level2")
+#define TLSTREE_L3 ((const unsigned char *)"level3")
+#define TLSTREE_L_LENGTH 6
+
+#define TLSTREE_KEY_LENGTH 32
+
+struct TLSTREE_CTX_st {
+ uint64_t seq;
+ const TLSTREE_CONST *tlsconst;
+ HMAC_CTX ctx1, ctx2, ctx3;
+ unsigned char current[TLSTREE_KEY_LENGTH];
+};
+
+TLSTREE_CTX *
+TLSTREE_CTX_new(void)
+{
+ TLSTREE_CTX *ctx;
+
+ ctx = malloc(sizeof(TLSTREE_CTX));
+ if (!ctx)
+ return NULL;
+
+ HMAC_CTX_init(&ctx->ctx1);
+ HMAC_CTX_init(&ctx->ctx2);
+ HMAC_CTX_init(&ctx->ctx3);
+ ctx->tlsconst = NULL;
+
+ return ctx;
+}
+
+void
+TLSTREE_CTX_free(TLSTREE_CTX *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ HMAC_CTX_cleanup(&ctx->ctx1);
+ HMAC_CTX_cleanup(&ctx->ctx2);
+ HMAC_CTX_cleanup(&ctx->ctx3);
+}
+
+static int tlstree_one(HMAC_CTX *ctx, const unsigned char *label, uint64_t seq, unsigned char *out)
+{
+ unsigned char seed[8], *p = seed;
+ static const unsigned char data1[1] = { 0x01 };
+ static const unsigned char data2[2] = { 0x01, 0x00 };
+ int dummy = TLSTREE_KEY_LENGTH;
+
+ ll2c(seq, p);
+ return kdf_tree_block(ctx, data1, 1, label, TLSTREE_L_LENGTH, seed, 8, data2, 2, out, &dummy);
+}
+
+int
+TLSTREE_Init(TLSTREE_CTX *ctx,
+ const TLSTREE_CONST *tlsconst,
+ const EVP_MD *md, ENGINE *impl,
+ const unsigned char *key,
+ int key_length)
+{
+ unsigned char tmp[TLSTREE_KEY_LENGTH];
+
+ /* Support only reasonable cases, which allow simplification of KDF_TREE calls */
+ if (key_length != EVP_MD_size(md) ||
+ key_length != TLSTREE_KEY_LENGTH)
+ return 0;
+
+ if (!ctx || !tlsconst || !md || !key)
+ return 0;
+
+ ctx->tlsconst = tlsconst;
+ ctx->seq = 0;
+
+ if (!HMAC_Init_ex(&ctx->ctx1, key, TLSTREE_KEY_LENGTH, md, impl) ||
+ !tlstree_one(&ctx->ctx1, TLSTREE_L1, 0, tmp) ||
+ !HMAC_Init_ex(&ctx->ctx2, tmp, TLSTREE_KEY_LENGTH, md, impl) ||
+ !tlstree_one(&ctx->ctx2, TLSTREE_L2, 0, tmp) ||
+ !HMAC_Init_ex(&ctx->ctx3, tmp, TLSTREE_KEY_LENGTH, md, impl) ||
+ !tlstree_one(&ctx->ctx3, TLSTREE_L3, 0, ctx->current))
+ return 0;
+
+ return 1;
+}
+
+int
+TLSTREE_GET(TLSTREE_CTX *ctx,
+ unsigned char *seq,
+ unsigned char *out)
+{
+ uint64_t s;
+ unsigned char *p = seq;
+ unsigned char tmp[TLSTREE_KEY_LENGTH];
+
+ c2ll(p, s);
+
+ if ((s & ctx->tlsconst->c1) != (ctx->seq & ctx->tlsconst->c1)) {
+ if (!tlstree_one(&ctx->ctx1, TLSTREE_L1, 0, tmp) ||
+ !HMAC_Init_ex(&ctx->ctx2, tmp, TLSTREE_KEY_LENGTH, NULL, NULL))
+ return 0;
+ }
+ if ((s & ctx->tlsconst->c2) != (ctx->seq & ctx->tlsconst->c2)) {
+ if (!tlstree_one(&ctx->ctx2, TLSTREE_L2, 0, tmp) ||
+ !HMAC_Init_ex(&ctx->ctx3, tmp, TLSTREE_KEY_LENGTH, NULL, NULL))
+ return 0;
+ }
+ if ((s & ctx->tlsconst->c3) != (ctx->seq & ctx->tlsconst->c3)) {
+ if (!tlstree_one(&ctx->ctx3, TLSTREE_L3, 0, ctx->current))
+ return 0;
+ }
+
+ memcpy(out, ctx->current, TLSTREE_KEY_LENGTH);
+
+ return 1;
+}
--
2.17.1

View file

@ -0,0 +1,243 @@
From 6da2bfbafdce6ef876fe8645a01da835831f1f2a Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Sat, 18 Apr 2020 18:42:12 +0300
Subject: [PATCH 87/87] ssl: add support for TLSTREE rekeying
CTR-OMAC ciphersuites use TLSTREE rekeying to change keys regularly.
Handle TLSTREE rekeying for those ciphersuites.
Sponsored by ROSA Linux
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/s3_lib.c | 18 +++++++++++++++--
src/lib/libssl/ssl.h | 6 ++++++
src/lib/libssl/ssl_lib.c | 14 +++++++++++++
src/lib/libssl/ssl_locl.h | 4 ++++
src/lib/libssl/t1_enc.c | 42 +++++++++++++++++++++++++++++++++++++++
5 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index ba87e9101..2636cfd4f 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -169,6 +169,18 @@
*/
#define FIXED_NONCE_LEN(x) (((x / 2) & 0xf) << 24)
+static const TLSTREE_CONST tlstree_magma_ctr_omac = {
+ .c1 = UINT64_C(0xFFFFFFC000000000),
+ .c2 = UINT64_C(0xFFFFFFFFFE000000),
+ .c3 = UINT64_C(0xFFFFFFFFFFFFF000),
+};
+
+static const TLSTREE_CONST tlstree_kuznyechik_ctr_omac = {
+ .c1 = UINT64_C(0xFFFFFFFF00000000),
+ .c2 = UINT64_C(0xFFFFFFFFFFF80000),
+ .c3 = UINT64_C(0xFFFFFFFFFFFFFFC0),
+};
+
/* list of available SSLv3 ciphers (sorted by id) */
SSL_CIPHER ssl3_ciphers[] = {
@@ -1318,7 +1330,8 @@ SSL_CIPHER ssl3_ciphers[] = {
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256|TLS1_NONCE_ADD_SEQUENCE,
.strength_bits = 256,
- .alg_bits = 256
+ .alg_bits = 256,
+ .tlstree = &tlstree_kuznyechik_ctr_omac,
},
/* Cipher C101 */
@@ -1334,7 +1347,8 @@ SSL_CIPHER ssl3_ciphers[] = {
.algo_strength = SSL_HIGH,
.algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256|TLS1_NONCE_ADD_SEQUENCE,
.strength_bits = 256,
- .alg_bits = 256
+ .alg_bits = 256,
+ .tlstree = &tlstree_magma_ctr_omac,
},
/* Cipher C102 */
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index 1c5e174b8..a9f414224 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -153,6 +153,8 @@
#include <openssl/bio.h>
+#include <openssl/kdftree.h>
+
#ifndef OPENSSL_NO_DEPRECATED
#include <openssl/buffer.h>
#include <openssl/crypto.h>
@@ -397,6 +399,10 @@ struct ssl_cipher_st {
unsigned long algorithm2; /* Extra flags */
int strength_bits; /* Number of bits really used */
int alg_bits; /* Number of bits for algorithm */
+
+#ifndef OPENSSL_NO_GOST
+ const TLSTREE_CONST *tlstree; /* TLSTREE parameters */
+#endif
};
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index c989d802c..a54c01dc7 100644
--- a/src/lib/libssl/ssl_lib.c
+++ b/src/lib/libssl/ssl_lib.c
@@ -2545,6 +2545,13 @@ ssl_clear_cipher_read_state(SSL *s)
free(s->internal->aead_read_ctx);
s->internal->aead_read_ctx = NULL;
}
+
+#ifndef OPENSSL_NO_GOST
+ if (S3I(s)->read.tlstree_cipher != NULL)
+ TLSTREE_CTX_free(S3I(s)->read.tlstree_cipher);
+ if (S3I(s)->read.tlstree_mac != NULL)
+ TLSTREE_CTX_free(S3I(s)->read.tlstree_mac);
+#endif
}
void
@@ -2561,6 +2568,13 @@ ssl_clear_cipher_write_state(SSL *s)
free(s->internal->aead_write_ctx);
s->internal->aead_write_ctx = NULL;
}
+
+#ifndef OPENSSL_NO_GOST
+ if (S3I(s)->write.tlstree_cipher != NULL)
+ TLSTREE_CTX_free(S3I(s)->write.tlstree_cipher);
+ if (S3I(s)->write.tlstree_mac != NULL)
+ TLSTREE_CTX_free(S3I(s)->write.tlstree_mac);
+#endif
}
/* Fix this function so that it takes an optional type parameter */
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index dc291ae4f..6871b01a9 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -811,6 +811,10 @@ typedef struct ssl3_rw_state_internal_st {
unsigned char mac_secret[EVP_MAX_MD_SIZE];
int cipher_iv_size;
unsigned char cipher_iv[EVP_MAX_IV_LENGTH];
+#ifndef OPENSSL_NO_GOST
+ TLSTREE_CTX *tlstree_cipher;
+ TLSTREE_CTX *tlstree_mac;
+#endif
} SSL3_RW_STATE_INTERNAL;
typedef struct ssl3_state_internal_st {
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 7ed6825a1..a4219599d 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -411,6 +411,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
const EVP_MD *mac;
const EVP_CIPHER *mac_cipher;
int mac_type;
+ SSL3_RW_STATE_INTERNAL *rws;
cipher = S3I(s)->tmp.new_sym_enc;
mac = S3I(s)->tmp.new_hash;
@@ -426,6 +427,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
goto err;
s->read_hash = mac_ctx;
+ rws = &S3I(s)->read;
} else {
/*
* DTLS fragments retain a pointer to the compression, cipher
@@ -443,6 +445,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
goto err;
s->internal->write_hash = mac_ctx;
+ rws = &S3I(s)->write;
}
EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read);
@@ -465,6 +468,24 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
else
s->internal->write_mac_size = mac_size;
+#ifndef OPENSSL_NO_GOST
+ if (s->session->cipher->tlstree) {
+ rws->tlstree_cipher = TLSTREE_CTX_new();
+ rws->tlstree_mac = TLSTREE_CTX_new();
+ if (rws->tlstree_cipher == NULL ||
+ rws->tlstree_mac == NULL ||
+ !TLSTREE_Init(rws->tlstree_cipher,
+ s->session->cipher->tlstree,
+ EVP_streebog256(), NULL,
+ key, key_len) ||
+ !TLSTREE_Init(rws->tlstree_mac,
+ s->session->cipher->tlstree,
+ EVP_streebog256(), NULL,
+ mac_secret, mac_secret_size))
+ goto err;
+ }
+#endif
+
if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) {
int nid;
if (S3I(s)->hs.new_cipher->algorithm2 & SSL_HANDSHAKE_MAC_GOST94)
@@ -904,6 +925,14 @@ tls1_enc(SSL *s, int send)
return 0;
}
+#ifndef OPENSSL_NO_GOST
+ if (rws->tlstree_cipher != NULL) {
+ unsigned char tmp[EVP_MAX_KEY_LENGTH];
+ if (!TLSTREE_GET(rws->tlstree_cipher, rws->sequence, tmp) ||
+ !EVP_CipherInit_ex(ds, NULL, NULL, tmp, NULL, -1))
+ return 0;
+ }
+#endif
if (add_nonce) {
unsigned char new_iv[EVP_MAX_IV_LENGTH];
int iv_size = rws->cipher_iv_size;
@@ -974,6 +1003,7 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
int stream_mac = ssl->session && ssl->session->cipher ?
ssl->session->cipher->algorithm2 & TLS1_STREAM_MAC :
0;
+ SSL3_RW_STATE_INTERNAL *rws;
int t;
if (send) {
@@ -981,11 +1011,13 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
seq = &(ssl->s3->internal->write.sequence[0]);
hash = ssl->internal->write_hash;
t = ssl->internal->write_mac_size;
+ rws = &S3I(ssl)->write;
} else {
rec = &(ssl->s3->internal->rrec);
seq = &(ssl->s3->internal->read.sequence[0]);
hash = ssl->read_hash;
t = ssl->read_mac_size;
+ rws = &S3I(ssl)->read;
}
OPENSSL_assert(t >= 0);
@@ -1028,6 +1060,16 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
ssl->s3->internal->read.mac_secret_size))
return -1;
} else {
+#ifndef OPENSSL_NO_GOST
+ if (rws->tlstree_mac != NULL) {
+ unsigned char tmp[EVP_MAX_KEY_LENGTH];
+ if (mac_ctx->pctx == NULL ||
+ !TLSTREE_GET(rws->tlstree_mac, seq, tmp) ||
+ EVP_PKEY_CTX_ctrl(mac_ctx->pctx, -1, EVP_PKEY_OP_SIGNCTX,
+ EVP_PKEY_CTRL_SET_MAC_KEY, rws->mac_secret_size, tmp) <= 0)
+ return -1;
+ }
+#endif
EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
t = EVP_DigestSignFinal(mac_ctx, md, &md_size);
--
2.17.1

View file

@ -0,0 +1,15 @@
Index: libressl-3.1.0/crypto/Makefile.am
===================================================================
--- libressl-3.1.0.orig/crypto/Makefile.am
+++ libressl-3.1.0/crypto/Makefile.am
@@ -723,6 +723,10 @@ libcrypto_la_SOURCES += modes/cts128.c
libcrypto_la_SOURCES += modes/gcm128.c
libcrypto_la_SOURCES += modes/ofb128.c
libcrypto_la_SOURCES += modes/xts128.c
+libcrypto_la_SOURCES += modes/cbc64.c
+libcrypto_la_SOURCES += modes/cfb64.c
+libcrypto_la_SOURCES += modes/ctr64.c
+libcrypto_la_SOURCES += modes/ofb64.c
noinst_HEADERS += modes/modes_lcl.h
# objects

View file

@ -0,0 +1,12 @@
Index: libressl-3.1.0/crypto/Makefile.am
===================================================================
--- libressl-3.1.0.orig/crypto/Makefile.am
+++ libressl-3.1.0/crypto/Makefile.am
@@ -638,6 +638,7 @@ libcrypto_la_SOURCES += evp/e_des.c
libcrypto_la_SOURCES += evp/e_des3.c
libcrypto_la_SOURCES += evp/e_gost2814789.c
libcrypto_la_SOURCES += evp/e_idea.c
+libcrypto_la_SOURCES += evp/e_magma.c
libcrypto_la_SOURCES += evp/e_null.c
libcrypto_la_SOURCES += evp/e_old.c
libcrypto_la_SOURCES += evp/e_rc2.c

View file

@ -0,0 +1,24 @@
Index: libressl-3.1.0/crypto/Makefile.am
===================================================================
--- libressl-3.1.0.orig/crypto/Makefile.am
+++ libressl-3.1.0/crypto/Makefile.am
@@ -638,6 +638,7 @@ libcrypto_la_SOURCES += evp/e_des.c
libcrypto_la_SOURCES += evp/e_des3.c
libcrypto_la_SOURCES += evp/e_gost2814789.c
libcrypto_la_SOURCES += evp/e_idea.c
+libcrypto_la_SOURCES += evp/e_kuznyechik.c
libcrypto_la_SOURCES += evp/e_magma.c
libcrypto_la_SOURCES += evp/e_null.c
libcrypto_la_SOURCES += evp/e_old.c
@@ -698,9 +699,11 @@ libcrypto_la_SOURCES += gost/gostr341001
libcrypto_la_SOURCES += gost/gostr341001_params.c
libcrypto_la_SOURCES += gost/gostr341001_pmeth.c
libcrypto_la_SOURCES += gost/gostr341194.c
+libcrypto_la_SOURCES += gost/kuznyechik.c
libcrypto_la_SOURCES += gost/streebog.c
noinst_HEADERS += gost/gost_asn1.h
noinst_HEADERS += gost/gost_locl.h
+noinst_HEADERS += gost/kuztable.h
# hkdf
libcrypto_la_SOURCES += hkdf/hkdf.c

View file

@ -0,0 +1,26 @@
Index: libressl-3.1.0/crypto/Makefile.am
===================================================================
--- libressl-3.1.0.orig/crypto/Makefile.am
+++ libressl-3.1.0/crypto/Makefile.am
@@ -721,6 +721,9 @@ libcrypto_la_SOURCES += idea/i_ofb64.c
libcrypto_la_SOURCES += idea/i_skey.c
noinst_HEADERS += idea/idea_lcl.h
+# kdftree
+libcrypto_la_SOURCES += kdftree/kdftree.c
+
# lhash
libcrypto_la_SOURCES += lhash/lh_stats.c
libcrypto_la_SOURCES += lhash/lhash.c
Index: libressl-3.1.0/include/openssl/Makefile.am
===================================================================
--- libressl-3.1.0.orig/include/openssl/Makefile.am
+++ libressl-3.1.0/include/openssl/Makefile.am
@@ -35,6 +35,7 @@ opensslinclude_HEADERS += gost.h
opensslinclude_HEADERS += hkdf.h
opensslinclude_HEADERS += hmac.h
opensslinclude_HEADERS += idea.h
+opensslinclude_HEADERS += kdftree.h
opensslinclude_HEADERS += lhash.h
opensslinclude_HEADERS += md4.h
opensslinclude_HEADERS += md5.h

View file

@ -0,0 +1,13 @@
Index: libressl-3.1.0/crypto/Makefile.am
===================================================================
--- libressl-3.1.0.orig/crypto/Makefile.am
+++ libressl-3.1.0/crypto/Makefile.am
@@ -693,6 +693,7 @@ libcrypto_la_SOURCES += gost/gost89imit_
libcrypto_la_SOURCES += gost/gost89imit_pmeth.c
libcrypto_la_SOURCES += gost/gost_asn1.c
libcrypto_la_SOURCES += gost/gost_err.c
+libcrypto_la_SOURCES += gost/gost_kdf.c
libcrypto_la_SOURCES += gost/gostr341001.c
libcrypto_la_SOURCES += gost/gostr341001_ameth.c
libcrypto_la_SOURCES += gost/gostr341001_key.c

View file

@ -0,0 +1,12 @@
Index: libressl-3.1.0/crypto/Makefile.am
===================================================================
--- libressl-3.1.0.orig/crypto/Makefile.am
+++ libressl-3.1.0/crypto/Makefile.am
@@ -746,6 +746,7 @@ libcrypto_la_SOURCES += modes/cfb128.c
libcrypto_la_SOURCES += modes/ctr128.c
libcrypto_la_SOURCES += modes/cts128.c
libcrypto_la_SOURCES += modes/gcm128.c
+libcrypto_la_SOURCES += modes/mgm128.c
libcrypto_la_SOURCES += modes/ofb128.c
libcrypto_la_SOURCES += modes/xts128.c
libcrypto_la_SOURCES += modes/cbc64.c

View file

@ -0,0 +1,12 @@
Index: libressl-3.1.0/crypto/Makefile.am
===================================================================
--- libressl-3.1.0.orig/crypto/Makefile.am
+++ libressl-3.1.0/crypto/Makefile.am
@@ -752,6 +752,7 @@ libcrypto_la_SOURCES += modes/xts128.c
libcrypto_la_SOURCES += modes/cbc64.c
libcrypto_la_SOURCES += modes/cfb64.c
libcrypto_la_SOURCES += modes/ctr64.c
+libcrypto_la_SOURCES += modes/mgm64.c
libcrypto_la_SOURCES += modes/ofb64.c
noinst_HEADERS += modes/modes_lcl.h

View file

@ -0,0 +1,13 @@
Index: libressl-3.1.0/crypto/Makefile.am
===================================================================
--- libressl-3.1.0.orig/crypto/Makefile.am
+++ libressl-3.1.0/crypto/Makefile.am
@@ -724,6 +724,8 @@ noinst_HEADERS += idea/idea_lcl.h
# kdftree
libcrypto_la_SOURCES += kdftree/kdftree.c
+libcrypto_la_SOURCES += kdftree/tlstree.c
+noinst_HEADERS += kdftree/kdftree_locl.h
# lhash
libcrypto_la_SOURCES += lhash/lh_stats.c

View file

@ -0,0 +1,38 @@
Index: portable-44a6a2397fb9b8d6868ef73d51e6ef79c39b0322/openbsd/src/lib/libcrypto/Symbols.list
===================================================================
--- portable-44a6a2397fb9b8d6868ef73d51e6ef79c39b0322.orig/openbsd/src/lib/libcrypto/Symbols.list
+++ portable-44a6a2397fb9b8d6868ef73d51e6ef79c39b0322/openbsd/src/lib/libcrypto/Symbols.list
@@ -2586,6 +2586,10 @@ SXNET_get_id_asc
SXNET_get_id_ulong
SXNET_it
SXNET_new
+TLSTREE_CTX_free
+TLSTREE_CTX_new
+TLSTREE_GET
+TLSTREE_Init
TS_ACCURACY_dup
TS_ACCURACY_free
TS_ACCURACY_get_micros
@@ -3560,6 +3564,8 @@ get_rfc3526_prime_3072
get_rfc3526_prime_4096
get_rfc3526_prime_6144
get_rfc3526_prime_8192
+gost_kexp15
+gost_kimp15
hex_to_string
i2a_ACCESS_DESCRIPTION
i2a_ASN1_ENUMERATED
Index: portable-44a6a2397fb9b8d6868ef73d51e6ef79c39b0322/update.sh
===================================================================
--- portable-44a6a2397fb9b8d6868ef73d51e6ef79c39b0322.orig/update.sh
+++ portable-44a6a2397fb9b8d6868ef73d51e6ef79c39b0322/update.sh
@@ -133,7 +133,7 @@ copy_hdrs $libcrypto_src "stack/stack.h
md4/md4.h ripemd/ripemd.h whrlpool/whrlpool.h idea/idea.h
rc2/rc2.h rc4/rc4.h ui/ui_compat.h txt_db/txt_db.h
sm3/sm3.h sm4/sm4.h chacha/chacha.h evp/evp.h poly1305/poly1305.h
- camellia/camellia.h gost/gost.h curve25519/curve25519.h"
+ camellia/camellia.h gost/gost.h curve25519/curve25519.h kdftree/kdftree.h"
copy_hdrs $libssl_src "srtp.h ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h"

View file

@ -3,9 +3,9 @@ From: Jan Engelhardt <jengelh@inai.de>
Date: Thu, 9 Jul 2020 14:11:14 +0000 Date: Thu, 9 Jul 2020 14:11:14 +0000
Subject: [PATCH] SUSE-extra-symver.patch Subject: [PATCH] SUSE-extra-symver.patch
Redefined by Oleg Solvev <o.solovev@rosalinux.ru>
Add symbol versions into the library to be on par with openssl. Add symbol versions into the library to be on par with openssl.
Rediffed by Oleg Solvev <o.solovev@rosalinux.ru>
--- ---
crypto/Makefile.am | 7 ++++++- crypto/Makefile.am | 7 ++++++-
ssl/Makefile.am | 7 ++++++- ssl/Makefile.am | 7 ++++++-

View file

@ -60,23 +60,163 @@
%define libcrypto_pkg %mklibname crypto_libressl %{libcrypto_sover} %define libcrypto_pkg %mklibname crypto_libressl %{libcrypto_sover}
%define libtls_pkg %mklibname tls_libressl %{libtls_sover} %define libtls_pkg %mklibname tls_libressl %{libtls_sover}
# parent commit of https://github.com/libressl-portable/openbsd/commit/a177033
# from which v3.2.0 is tagged
%define commit_openbsd 768c7156952b7df8245172586ca8c4c37d599a47
# https://github.com/libressl-portable/portable is tagged correctly,
# but lets also build from commit for consistency
%define commit_portable 44a6a2397fb9b8d6868ef73d51e6ef79c39b0322
%define _default_patch_fuzz 3
%define config_update %{nil}
# TODO: fix it, introduced by patches from gost-new
%define _disable_ld_no_undefined 1
Summary: LibreSSL utils and libs coexisting with OpenSSL Summary: LibreSSL utils and libs coexisting with OpenSSL
Name: libressl Name: libressl
Version: 3.2.0 Version: 3.2.0
Release: 2 Release: 3
# The code is distributed under ISC license except of original OpenSSL code # The code is distributed under ISC license except of original OpenSSL code
License: ISC and BSD-like License: ISC and BSD-like
Group: System/Base Group: System/Base
Url: http://libressl.org Url: http://libressl.org
Source0: https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-%{version}.tar.gz #Source0: https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-%{version}.tar.gz
Source0: https://github.com/libressl-portable/portable/archive/%{commit_portable}.tar.gz?/libressl-portable-%{commit_portable}.tar.gz
Source1: https://github.com/libressl-portable/openbsd/archive/%{commit_openbsd}.tar.gz?/libressl-openbsd-%{commit_openbsd}.tar.gz
Source10: libressl.rpmlintrc Source10: libressl.rpmlintrc
# TODO: add printing config location to `openssl version`
Patch1: 0001-Allow-custom-config-location.patch # Patches for openbsd tree are also commited here:
# https://github.com/mikhailnov/libressl-openbsd/commits/rosa-v3.2.0
# ROSA patch, TODO: add printing config location to `openssl version`
Patch0001: 0001-Allow-custom-config-location.patch
# Support of GOST 2015 and other fixes by lumag@, sponsored by ROSA Linux
# Поддержка TLS 1.2 CNT-IMIT и CTR-OMAC в соответствии с Р 1323565.1.020-2018 и
# draft-smyshlyaev-tls12-gost-suites.
# - Блочные шифры Магма, Кузнечик по ГОСТ Р 34.12-2015.
# - Режимы блочных шифров по ГОСТ Р 34.13-2015
# - Режим CTR-ACPKM по Р 1323565.1.017-2018
# - Режим MGM по Р 13235651.026-2019
# - Формат ключей по Р 1323565.1.023-2018
# - Параметры эллиптических кривых по Р 1323565.1.024-2019
# - Поддержка файлов CMS и PKCS7 по RFC 4490 (в режиме KeyTransport)
# - Поддержка файлов CMS и PKCS7 по Р 1323565.1.025-2019 (кроме режима KEK)
# - Поддержка файлов PKCS#8/PKCS#12 по Р 50.1.112-2016.
# - Поддержка криптонаборов TLS 1.2 по Р 1323565.1.020-2018
# Для поддержки криптонаборов TLS 1.3 с точки зрения ГОСТ все готово,
# поддержка TLS 1.3 в самом LibreSSL пока находится в процессе разработки.
# In process of upstreamization which is going not easily...
# git clone https://github.com/GostCrypt/libressl-openbsd.git -b gost-new
# cd libressl-openbsd
# git format-patch -64 --start-number=101
# ( for i in 01*.patch ; do echo Patch$(echo $i | awk -F '-' '{print $1}'): $i ; done ) | sort -h
# cherry-picked from upstream after v3.2.0 and gost-new
Patch0002: 0002-Remove-expired-certificate-ok-tb.patch
Patch0003: 0003-Properly-document-PKCS7_final-3-which-was-already-me.patch
Patch0004: 0004-distracting-whitespace.patch
Patch0005: 0005-new-manual-page-PKCS7_add_attribute-3.patch
Patch0006: 0006-mention-that-TLS_method-3-also-supports-TLSv1.3.patch
Patch0007: 0007-minor-polishing.patch
Patch0008: 0008-Apply-some-style-9.patch
Patch0009: 0009-Add-support-for-additional-GOST-curves.patch
Patch0010: 0010-Add-a-few-more-errors-to-help-debugging.patch
Patch0011: 0011-Add-OIDs-for-HMAC-using-Streebog-GOST-R-34.11-2012-h.patch
Patch0012: 0012-Allow-GOST-R-34.11-2012-in-PBE-PBKDF2-PKCS-5.patch
Patch0013: 0013-Enable-GOST_SIG_FORMAT_RS_LE-when-verifying-certific.patch
Patch0014: 0014-Handle-GOST-in-ssl_cert_dup.patch
Patch0015: 0015-Stop-sending-GOST-R-34.10-94-as-a-CertificateType.patch
Patch0016: 0016-Use-IANA-allocated-GOST-ClientCertificateTypes.patch
Patch0017: 0017-Add-a-custom-copy-handler-for-AES-key-wrap.patch
Patch0018: 0018-document-PKCS7_get_signer_info-3.patch
Patch0019: 0019-wording-tweaks-from-ross-l-richardson-and-tb.patch
Patch0020: 0020-document-PEM_ASN1_read-3-and-PEM_ASN1_read_bio-3.patch
Patch0021: 0021-add-a-comment-saying-that-name_cmp-is-intentionally-.patch
Patch0022: 0022-add-my-Copyright-and-license-which-i-forgot-when-add.patch
Patch0023: 0023-Document-PEM_def_callback-3.patch
Patch0024: 0024-Document-EVP_read_pw_string_min-3.patch
Patch0025: 0025-gost-populate-params-tables-with-new-curves.patch
Patch0026: 0026-gost-use-ECerror-to-report-EC-errors.patch
Patch0027: 0027-gost-support-new-PublicKeyParameters-format.patch
Patch0028: 0028-gostr341001-support-unwrapped-private-keys-support.patch
Patch0029: 0029-pkcs12-add-support-for-GOST-PFX-files.patch
Patch0030: 0030-modes-add-functions-implementing-common-code-for-64-.patch
Patch0031: 0031-gost-drop-key_len-from-Gost28147_set_key.patch
Patch0032: 0032-gost-use-key_meshing-for-specifying-section-size.patch
Patch0033: 0033-gost-add-support-for-magma-cipher.patch
Patch0034: 0034-gost-add-support-for-kuznyechik-cipher.patch
Patch0035: 0035-kuznyechik-fix-IV-handling-for-CTR-mode.patch
Patch0036: 0036-magma-fix-IV-handling-for-CTR-mode.patch
Patch0037: 0037-gost-add-support-for-ACPKM-rekeying.patch
Patch0038: 0038-gost-add-support-for-GOST-34.12-Magma-Kuznyechik-enc.patch
Patch0039: 0039-gost-add-support-for-magma-ctr-acpkm-mode.patch
Patch0040: 0040-gost-add-support-for-kuznyechik-ctr-acpkm-mode.patch
Patch0041: 0041-kdftree-add-functions-implementing-KDF_TREE-function.patch
Patch0042: 0042-gost-add-support-for-new-GOST-key-transport-data-for.patch
Patch0043: 0043-modes-add-support-for-128-bit-MGM-mode.patch
Patch0044: 0044-modes-add-support-for-64-bit-MGM-mode.patch
Patch0045: 0045-gost-add-kuznyechik-mgm-support.patch
Patch0046: 0046-gost-add-magma-mgm-support.patch
Patch0047: 0047-regress-evp-add-simple-test-for-AEAD-ciphers.patch
Patch0048: 0048-evp-add-EVP_CIPHER-interface-for-kuznyechik-mgm.patch
Patch0049: 0049-evp-add-EVP_CIPHER-interface-for-magma-mgm.patch
Patch0050: 0050-evp-add-support-for-Kuznyechik-ctr-acpkm-omac-cipher.patch
Patch0051: 0051-evp-add-support-for-Magma-ctr-acpkm-omac-cipher.patch
Patch0052: 0052-gost-restore-CMS-support.patch
Patch0053: 0053-gost-add-support-for-CMS-and-SMIME-enveloped-files.patch
Patch0054: 0054-cms-add-support-for-using-AEAD-ciphers-in-CMS-files.patch
Patch0055: 0055-cms-populate-SMIMECaps-with-new-GOST-algorithms.patch
Patch0056: 0056-cms-allow-keys-support-different-RI-types.patch
Patch0057: 0057-evp-support-kuznyechik-kexp15-keywrap-algorithm.patch
Patch0058: 0058-evp-support-magma-kexp15-keywrap-algorithm.patch
Patch0059: 0059-gost-support-specifying-old-or-new-KEG-derivation-fo.patch
Patch0060: 0060-cms-add-support-for-setting-KeyAgreement-UKM.patch
Patch0061: 0061-cms-select-proper-cipher-for-GOST-KeyAgreeement.patch
Patch0062: 0062-cms-specify-originator-key-for-KeyAgreement-decoding.patch
Patch0063: 0063-cms-support-specifying-originator-certificate-and-ke.patch
Patch0064: 0064-gost-add-support-for-decoding-KeyAgreement-CMS-files.patch
Patch0065: 0065-cms-autoguess-preferred-RecipientInfo-type.patch
Patch0066: 0066-Fix-S-Box-used-for-CipherKeyExchange-message-in-GOST.patch
Patch0067: 0067-gost-pmeth-check-that-result-of-data-encryption-woul.patch
Patch0068: 0068-ssl_sigalgs-select-proper-default-algorithm-for-GOST.patch
Patch0069: 0069-ssl-add-support-for-IANA-allocated-GOST-sigalgs-valu.patch
Patch0070: 0070-ssl-provide-interoperability-with-CryptoPro-CSP.patch
Patch0071: 0071-ssl-do-not-send-GOST-94-certificate-type.patch
Patch0072: 0072-ssl-add-support-for-new-GOST-CNT-IMIT-ciphersuite-va.patch
Patch0073: 0073-evp-add-EVP_PKEY_new_CMAC_key-function.patch
Patch0074: 0074-evp-fix-sign-verify-for-EVP_PKEY_CMAC-keys.patch
Patch0075: 0075-evp-fix-EVP_MD_CTX_copy_ex-for-CMAC-contexts.patch
Patch0076: 0076-objects-add-id-for-gost-kdf-key-exchange-for-CTR-OMA.patch
Patch0077: 0077-ssl-add-defines-for-GOST-CTR-OMAC-ciphersuites.patch
Patch0078: 0078-ssl-add-support-for-GOST-KDF-key-exchange.patch
Patch0079: 0079-ssl-support-selecting-CMAC-for-CTR-OMAC-ciphersuites.patch
Patch0080: 0080-ssl-select-ACPKM-session-size-for-CTR-OMAC-ciphersui.patch
Patch0081: 0081-ssl-fix-Finished-message-length-for-CTR-OMAC-ciphers.patch
Patch0082: 0082-ssl-fix-CMAC-support.patch
Patch0083: 0083-ssl-merge-read-and-write-sequence-secrets-into-commo.patch
Patch0084: 0084-ssl-drop-mac_flags-field.patch
Patch0085: 0085-ssl-support-IV-increments-for-GOST-CTR-OMAC-ciphersu.patch
Patch0086: 0086-kdftree-add-support-for-TLSTREE-rekeying-algorithm.patch
Patch0087: 0087-ssl-add-support-for-TLSTREE-rekeying.patch
# Patches for portable, from lumag@
# ( for i in *PORTABLE*.patch ; do echo Patch$(echo $i | awk -F '-' '{print $2}'): $i ; done ) | sed -e 's,^Patch0,Patch2,g' | sort -h
# These patches for portable tree extend patches above for openbsd tree
# and have the same numbers
Patch2030: PORTABLE-0030-modes-add-functions-implementing-common-code-for-64-.patch
Patch2033: PORTABLE-0033-gost-add-support-for-magma-cipher.patch
Patch2034: PORTABLE-0034-gost-add-support-for-kuznyechik-cipher.patch
Patch2041: PORTABLE-0041-kdftree-add-functions-implementing-KDF_TREE-function.patch
Patch2042: PORTABLE-0042-gost-add-support-for-new-GOST-key-transport-data-for.patch
Patch2043: PORTABLE-0043-modes-add-support-for-128-bit-MGM-mode.patch
Patch2044: PORTABLE-0044-modes-add-support-for-64-bit-MGM-mode.patch
Patch2086: PORTABLE-0086-kdftree-add-support-for-TLSTREE-rekeying-algorithm.patch
Patch2100: PORTABLE-0100-fixup-build.patch
# If both openssl and libressl libraries are loaded into one runtime, # If both openssl and libressl libraries are loaded into one runtime,
# versioning their symbols will or may allow them to coexist # versioning their symbols will or may allow them to coexist
Patch2: SUSE-extra-symver.patch Patch2200: PORTABLE-2200-SUSE-extra-symver.patch
# https://github.com/GostCrypt/libressl-openbsd/tree/gost-new
Patch3: 0001-gost-restore-CMS-support.patch
# From https://www.mitchr.me/SS/exampleCode/openssl.html # From https://www.mitchr.me/SS/exampleCode/openssl.html
Source20: test.c Source20: test.c
Source22: test2.c Source22: test2.c
@ -253,19 +393,33 @@ capabilities.
#------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------
%prep %prep
%setup -q -n libressl-%{version} %setup -q -n portable-%{commit_portable} -a1
%patch2 -p1 # Emulating creation of release tarball...
# Patch is against gits https://github.com/libressl-portable/ mv openbsd-%{commit_openbsd} openbsd
# Release tarball is packaged in a tricky way ( cd openbsd
cat %{PATCH1} | sed \ # First apply patches and then run a script which will copy files etc.
-e 's,src/lib/libcrypto/,crypto/,g' \ for i in $(echo "%patches" | sed -e 's,[[:space:]],\n,g' | grep -v '/PORTABLE\-' | sort -h); do
-e 's,src/usr.bin/openssl/,apps/openssl/,g' \ echo "Applying openbsd patch $i"
> 1.patch patch -p1 < "$i"
patch -p1 < 1.patch done
cat %{PATCH3} | sed \ # TODO: fix patch 0163-ssl-add-support-for-TLSTREE-rekeying.patch, src/lib/libssl/ssl.h etc.
-e 's,src/lib/libcrypto/,crypto/,g' \ grep -Irl '#include <openssl/kdftree.h>' | xargs sed -i -e "s,#include <openssl/kdftree.h>,#include \"${PWD}/src/lib/libcrypto/kdftree/kdftree.h\",g"
> 3.patch )
patch -p1 < 3.patch sed -i -e 's,git ,true ,g' update.sh
sed -i -e 's,./update.sh,sh -x ./update.sh,g' autogen.sh
sh -x ./autogen.sh | tee autogen0.log
# Protection against incorrect updates, e.g. by updates_tracker
grep -q "^LibreSSL version %{version}$" autogen0.log
rm -f autogen0.log
# Now apply patches on top of portable edition after all files have been generated
for i in $(echo "%patches" | sed -e 's,[[:space:]],\n,g' | grep '/PORTABLE\-' | sort -h); do
echo "Applying portable patch $i"
patch -p1 < "$i"
done
# Rerun after patching
sh -x update.sh
%build %build
%setup_compile_flags %setup_compile_flags
@ -273,7 +427,7 @@ patch -p1 < 3.patch
# Use the same %%_openssl dir with OpenSSL, but separate the config # Use the same %%_openssl dir with OpenSSL, but separate the config
# (note that we patch libressl, X509_CONF_FILE is not upstream) # (note that we patch libressl, X509_CONF_FILE is not upstream)
export CFLAGS="$CFLAGS -DX509_CONF_FILE='\"%{_openssldir}/libressl.cnf\"'" export CFLAGS="$CFLAGS -DX509_CONF_FILE='\"%{_openssldir}/libressl.cnf\"'"
autoreconf -if #patch2 #autoreconf -if #Source21
# static libs are required for tests target in Makefile # static libs are required for tests target in Makefile
%configure \ %configure \
--enable-nc \ --enable-nc \