@@ -26,6 +26,7 @@ import (
26
26
"crypto/internal/fips140"
27
27
"crypto/internal/fips140/aes"
28
28
"crypto/internal/fips140/aes/gcm"
29
+ "crypto/internal/fips140/bigmod"
29
30
"crypto/internal/fips140/drbg"
30
31
"crypto/internal/fips140/ecdh"
31
32
"crypto/internal/fips140/ecdsa"
@@ -35,6 +36,7 @@ import (
35
36
"crypto/internal/fips140/hmac"
36
37
"crypto/internal/fips140/mlkem"
37
38
"crypto/internal/fips140/pbkdf2"
39
+ "crypto/internal/fips140/rsa"
38
40
"crypto/internal/fips140/sha256"
39
41
"crypto/internal/fips140/sha3"
40
42
"crypto/internal/fips140/sha512"
@@ -131,6 +133,8 @@ var (
131
133
// https://pages.nist.gov/ACVP/draft-vassilev-acvp-drbg.html#section-7.2
132
134
// KDF-Counter algorithm capabilities:
133
135
// https://pages.nist.gov/ACVP/draft-celi-acvp-kbkdf.html#section-7.3
136
+ // RSA algorithm capabilities:
137
+ // https://pages.nist.gov/ACVP/draft-celi-acvp-rsa.html#section-7.3
134
138
//go:embed acvp_capabilities.json
135
139
capabilitiesJson []byte
136
140
@@ -269,6 +273,26 @@ var (
269
273
"ctrDRBG-reseed/AES-256" : cmdCtrDrbgReseedAft (),
270
274
271
275
"KDF-counter" : cmdKdfCounterAft (),
276
+
277
+ "RSA/keyGen" : cmdRsaKeyGenAft (),
278
+
279
+ "RSA/sigGen/SHA2-224/pkcs1v1.5" : cmdRsaSigGenAft (func () fips140.Hash { return sha256 .New224 () }, "SHA-224" , false ),
280
+ "RSA/sigGen/SHA2-256/pkcs1v1.5" : cmdRsaSigGenAft (func () fips140.Hash { return sha256 .New () }, "SHA-256" , false ),
281
+ "RSA/sigGen/SHA2-384/pkcs1v1.5" : cmdRsaSigGenAft (func () fips140.Hash { return sha512 .New384 () }, "SHA-384" , false ),
282
+ "RSA/sigGen/SHA2-512/pkcs1v1.5" : cmdRsaSigGenAft (func () fips140.Hash { return sha512 .New () }, "SHA-512" , false ),
283
+ "RSA/sigGen/SHA2-224/pss" : cmdRsaSigGenAft (func () fips140.Hash { return sha256 .New224 () }, "SHA-224" , true ),
284
+ "RSA/sigGen/SHA2-256/pss" : cmdRsaSigGenAft (func () fips140.Hash { return sha256 .New () }, "SHA-256" , true ),
285
+ "RSA/sigGen/SHA2-384/pss" : cmdRsaSigGenAft (func () fips140.Hash { return sha512 .New384 () }, "SHA-384" , true ),
286
+ "RSA/sigGen/SHA2-512/pss" : cmdRsaSigGenAft (func () fips140.Hash { return sha512 .New () }, "SHA-512" , true ),
287
+
288
+ "RSA/sigVer/SHA2-224/pkcs1v1.5" : cmdRsaSigVerAft (func () fips140.Hash { return sha256 .New224 () }, "SHA-224" , false ),
289
+ "RSA/sigVer/SHA2-256/pkcs1v1.5" : cmdRsaSigVerAft (func () fips140.Hash { return sha256 .New () }, "SHA-256" , false ),
290
+ "RSA/sigVer/SHA2-384/pkcs1v1.5" : cmdRsaSigVerAft (func () fips140.Hash { return sha512 .New384 () }, "SHA-384" , false ),
291
+ "RSA/sigVer/SHA2-512/pkcs1v1.5" : cmdRsaSigVerAft (func () fips140.Hash { return sha512 .New () }, "SHA-512" , false ),
292
+ "RSA/sigVer/SHA2-224/pss" : cmdRsaSigVerAft (func () fips140.Hash { return sha256 .New224 () }, "SHA-224" , true ),
293
+ "RSA/sigVer/SHA2-256/pss" : cmdRsaSigVerAft (func () fips140.Hash { return sha256 .New () }, "SHA-256" , true ),
294
+ "RSA/sigVer/SHA2-384/pss" : cmdRsaSigVerAft (func () fips140.Hash { return sha512 .New384 () }, "SHA-384" , true ),
295
+ "RSA/sigVer/SHA2-512/pss" : cmdRsaSigVerAft (func () fips140.Hash { return sha512 .New () }, "SHA-512" , true ),
272
296
}
273
297
)
274
298
@@ -1634,14 +1658,133 @@ func cmdKdfCounterAft() command {
1634
1658
}
1635
1659
}
1636
1660
1661
+ func cmdRsaKeyGenAft () command {
1662
+ return command {
1663
+ requiredArgs : 1 , // Modulus bit-size
1664
+ handler : func (args [][]byte ) ([][]byte , error ) {
1665
+ bitSize := binary .LittleEndian .Uint32 (args [0 ])
1666
+
1667
+ key , err := getRSAKey ((int )(bitSize ))
1668
+ if err != nil {
1669
+ return nil , fmt .Errorf ("generating RSA key: %w" , err )
1670
+ }
1671
+
1672
+ N , e , d , P , Q , _ , _ , _ := key .Export ()
1673
+
1674
+ eBytes := make ([]byte , 4 )
1675
+ binary .BigEndian .PutUint32 (eBytes , uint32 (e ))
1676
+
1677
+ return [][]byte {eBytes , P , Q , N , d }, nil
1678
+ },
1679
+ }
1680
+ }
1681
+
1682
+ func cmdRsaSigGenAft (hashFunc func () fips140.Hash , hashName string , pss bool ) command {
1683
+ return command {
1684
+ requiredArgs : 2 , // Modulus bit-size, message
1685
+ handler : func (args [][]byte ) ([][]byte , error ) {
1686
+ bitSize := binary .LittleEndian .Uint32 (args [0 ])
1687
+ msg := args [1 ]
1688
+
1689
+ key , err := getRSAKey ((int )(bitSize ))
1690
+ if err != nil {
1691
+ return nil , fmt .Errorf ("generating RSA key: %w" , err )
1692
+ }
1693
+
1694
+ h := hashFunc ()
1695
+ h .Write (msg )
1696
+ digest := h .Sum (nil )
1697
+
1698
+ var sig []byte
1699
+ if ! pss {
1700
+ sig , err = rsa .SignPKCS1v15 (key , hashName , digest )
1701
+ if err != nil {
1702
+ return nil , fmt .Errorf ("signing RSA message: %w" , err )
1703
+ }
1704
+ } else {
1705
+ sig , err = rsa .SignPSS (rand .Reader , key , hashFunc (), digest , h .Size ())
1706
+ if err != nil {
1707
+ return nil , fmt .Errorf ("signing RSA message: %w" , err )
1708
+ }
1709
+ }
1710
+
1711
+ N , e , _ , _ , _ , _ , _ , _ := key .Export ()
1712
+ eBytes := make ([]byte , 4 )
1713
+ binary .BigEndian .PutUint32 (eBytes , uint32 (e ))
1714
+
1715
+ return [][]byte {N , eBytes , sig }, nil
1716
+ },
1717
+ }
1718
+ }
1719
+
1720
+ func cmdRsaSigVerAft (hashFunc func () fips140.Hash , hashName string , pss bool ) command {
1721
+ return command {
1722
+ requiredArgs : 4 , // n, e, message, signature
1723
+ handler : func (args [][]byte ) ([][]byte , error ) {
1724
+ nBytes := args [0 ]
1725
+ eBytes := args [1 ]
1726
+ msg := args [2 ]
1727
+ sig := args [3 ]
1728
+
1729
+ paddedE := make ([]byte , 4 )
1730
+ copy (paddedE [4 - len (eBytes ):], eBytes )
1731
+ e := int (binary .BigEndian .Uint32 (paddedE ))
1732
+
1733
+ n , err := bigmod .NewModulus (nBytes )
1734
+ if err != nil {
1735
+ return nil , fmt .Errorf ("invalid RSA modulus: %w" , err )
1736
+ }
1737
+
1738
+ pub := & rsa.PublicKey {
1739
+ N : n ,
1740
+ E : e ,
1741
+ }
1742
+
1743
+ h := hashFunc ()
1744
+ h .Write (msg )
1745
+ digest := h .Sum (nil )
1746
+
1747
+ if ! pss {
1748
+ err = rsa .VerifyPKCS1v15 (pub , hashName , digest , sig )
1749
+ } else {
1750
+ err = rsa .VerifyPSS (pub , hashFunc (), digest , sig )
1751
+ }
1752
+ if err != nil {
1753
+ return [][]byte {{0 }}, nil
1754
+ }
1755
+
1756
+ return [][]byte {{1 }}, nil
1757
+ },
1758
+ }
1759
+ }
1760
+
1761
+ // rsaKeyCache caches generated keys by modulus bit-size.
1762
+ var rsaKeyCache = map [int ]* rsa.PrivateKey {}
1763
+
1764
+ // getRSAKey returns a cached RSA private key with the specified modulus bit-size
1765
+ // or generates one if necessary.
1766
+ func getRSAKey (bits int ) (* rsa.PrivateKey , error ) {
1767
+ if key , exists := rsaKeyCache [bits ]; exists {
1768
+ return key , nil
1769
+ }
1770
+
1771
+ key , err := rsa .GenerateKey (rand .Reader , bits )
1772
+ if err != nil {
1773
+ return nil , err
1774
+ }
1775
+
1776
+ rsaKeyCache [bits ] = key
1777
+ return key , nil
1778
+ }
1779
+
1637
1780
func TestACVP (t * testing.T ) {
1638
1781
testenv .SkipIfShortAndSlow (t )
1639
1782
1640
1783
const (
1641
1784
bsslModule = "boringssl.googlesource.com/boringssl.git"
1642
1785
bsslVersion = "v0.0.0-20250116010235-21f54b2730ee"
1643
1786
goAcvpModule = "github.com/cpu/go-acvp"
1644
- goAcvpVersion = "v0.0.0-20250102201911-6839fc40f9f8 "
1787
+ goAcvpVersion = "v0.0.0-20250110181646-e47fea3b5d7d "
1645
1788
)
1646
1789
1647
1790
// In crypto/tls/bogo_shim_test.go the test is skipped if run on a builder with runtime.GOOS == "windows"
0 commit comments