]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/internal/fips/rsa: support all SHA hashes in PKCS#1 v1.5
authorFilippo Valsorda <filippo@golang.org>
Wed, 20 Nov 2024 14:02:40 +0000 (15:02 +0100)
committerGopher Robot <gobot@golang.org>
Wed, 20 Nov 2024 17:52:09 +0000 (17:52 +0000)
The byte sequences match those in
https://github.com/randombit/botan/blob/e5ec40828/src/lib/pk_pad/hash_id/hash_id.cpp

For #69536
Fixes #43923

Change-Id: I8b4daea71c2f696ad67ddc13affefd1563c51266
Reviewed-on: https://go-review.googlesource.com/c/go/+/630095
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
src/crypto/internal/fips/rsa/pkcs1v15.go
src/crypto/internal/fips/rsa/pkcs1v15_test.go [new file with mode: 0644]

index b52471bc01eecc56a410b05463df7a650b656082..a3f8f5b339da00e2d634bd67a625272958ebe47a 100644 (file)
@@ -23,14 +23,20 @@ import (
 // precompute a prefix of the digest value that makes a valid ASN1 DER string
 // with the correct contents.
 var hashPrefixes = map[string][]byte{
-       "MD5":        {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
-       "SHA-1":      {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
-       "SHA-224":    {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
-       "SHA-256":    {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
-       "SHA-384":    {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
-       "SHA-512":    {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
-       "MD5+SHA1":   {}, // A special TLS case which doesn't use an ASN1 prefix.
-       "RIPEMD-160": {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
+       "MD5":         {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
+       "SHA-1":       {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
+       "SHA-224":     {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
+       "SHA-256":     {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
+       "SHA-384":     {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
+       "SHA-512":     {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
+       "SHA-512/224": {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05, 0x05, 0x00, 0x04, 0x1C},
+       "SHA-512/256": {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20},
+       "SHA3-224":    {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1C},
+       "SHA3-256":    {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20},
+       "SHA3-384":    {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30},
+       "SHA3-512":    {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0a, 0x05, 0x00, 0x04, 0x40},
+       "MD5+SHA1":    {}, // A special TLS case which doesn't use an ASN1 prefix.
+       "RIPEMD-160":  {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
 }
 
 // SignPKCS1v15 calculates an RSASSA-PKCS1-v1.5 signature.
@@ -122,7 +128,8 @@ func verifyPKCS1v15(pub *PublicKey, hash string, hashed []byte, sig []byte) erro
 
 func checkApprovedHashName(hash string) {
        switch hash {
-       case "SHA-224", "SHA-256", "SHA-384", "SHA-512":
+       case "SHA-224", "SHA-256", "SHA-384", "SHA-512", "SHA-512/224", "SHA-512/256",
+               "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512":
        default:
                fips.RecordNonApproved()
        }
diff --git a/src/crypto/internal/fips/rsa/pkcs1v15_test.go b/src/crypto/internal/fips/rsa/pkcs1v15_test.go
new file mode 100644 (file)
index 0000000..5dae56e
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rsa
+
+import (
+       "bytes"
+       "crypto"
+       "crypto/x509/pkix"
+       "encoding/asn1"
+       "testing"
+)
+
+func TestHashPrefixes(t *testing.T) {
+       prefixes := map[crypto.Hash]asn1.ObjectIdentifier{
+               // RFC 3370, Section 2.1 and 2.2
+               //
+               // sha-1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+               //      oiw(14) secsig(3) algorithm(2) 26 }
+               //
+               // md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+               //      rsadsi(113549) digestAlgorithm(2) 5 }
+               crypto.MD5:  {1, 2, 840, 113549, 2, 5},
+               crypto.SHA1: {1, 3, 14, 3, 2, 26},
+
+               // https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
+               //
+               // nistAlgorithms OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) country(16) us(840)
+               //          organization(1) gov(101) csor(3) nistAlgorithm(4) }
+               //
+               // hashAlgs OBJECT IDENTIFIER ::= { nistAlgorithms 2 }
+               //
+               // id-sha256 OBJECT IDENTIFIER ::= { hashAlgs 1 }
+               // id-sha384 OBJECT IDENTIFIER ::= { hashAlgs 2 }
+               // id-sha512 OBJECT IDENTIFIER ::= { hashAlgs 3 }
+               // id-sha224 OBJECT IDENTIFIER ::= { hashAlgs 4 }
+               // id-sha512-224 OBJECT IDENTIFIER ::= { hashAlgs 5 }
+               // id-sha512-256 OBJECT IDENTIFIER ::= { hashAlgs 6 }
+               // id-sha3-224 OBJECT IDENTIFIER ::= { hashAlgs 7 }
+               // id-sha3-256 OBJECT IDENTIFIER ::= { hashAlgs 8 }
+               // id-sha3-384 OBJECT IDENTIFIER ::= { hashAlgs 9 }
+               // id-sha3-512 OBJECT IDENTIFIER ::= { hashAlgs 10 }
+               crypto.SHA224:     {2, 16, 840, 1, 101, 3, 4, 2, 4},
+               crypto.SHA256:     {2, 16, 840, 1, 101, 3, 4, 2, 1},
+               crypto.SHA384:     {2, 16, 840, 1, 101, 3, 4, 2, 2},
+               crypto.SHA512:     {2, 16, 840, 1, 101, 3, 4, 2, 3},
+               crypto.SHA512_224: {2, 16, 840, 1, 101, 3, 4, 2, 5},
+               crypto.SHA512_256: {2, 16, 840, 1, 101, 3, 4, 2, 6},
+               crypto.SHA3_224:   {2, 16, 840, 1, 101, 3, 4, 2, 7},
+               crypto.SHA3_256:   {2, 16, 840, 1, 101, 3, 4, 2, 8},
+               crypto.SHA3_384:   {2, 16, 840, 1, 101, 3, 4, 2, 9},
+               crypto.SHA3_512:   {2, 16, 840, 1, 101, 3, 4, 2, 10},
+       }
+
+       for h, oid := range prefixes {
+               want, err := asn1.Marshal(struct {
+                       HashAlgorithm pkix.AlgorithmIdentifier
+                       Hash          []byte
+               }{
+                       HashAlgorithm: pkix.AlgorithmIdentifier{
+                               Algorithm:  oid,
+                               Parameters: asn1.NullRawValue,
+                       },
+                       Hash: make([]byte, h.Size()),
+               })
+               if err != nil {
+                       t.Fatal(err)
+               }
+               want = want[:len(want)-h.Size()]
+               got := hashPrefixes[h.String()]
+               if !bytes.Equal(got, want) {
+                       t.Errorf("%s: got %x, want %x", h, got, want)
+               }
+       }
+}