1
2
3
4
5
6
7 package fipstest
8
9 import (
10 "crypto/internal/fips140/bigmod"
11 "crypto/internal/fips140/rsa"
12 "crypto/internal/fips140/sha256"
13 "crypto/internal/fips140/sha3"
14 "crypto/internal/fips140/sha512"
15 "crypto/rand"
16
17 _ "embed"
18 "encoding/binary"
19 "errors"
20 "fmt"
21 "hash"
22 "math/big"
23 )
24
25
26 var capabilitiesJson []byte
27
28 var testConfigFile = "acvp_test_fips140v1.28.config.json"
29
30 func init() {
31
32 commands["RSA/keyGen/crt"] = cmdRsaKeyGenCrtAft()
33
34
35
36 commands["RSA/sigGen/SHA2-224/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha256.New224() }, "SHA-224", false)
37 commands["RSA/sigGen/SHA2-256/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha256.New() }, "SHA-256", false)
38 commands["RSA/sigGen/SHA2-384/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha512.New384() }, "SHA-384", false)
39 commands["RSA/sigGen/SHA2-512/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha512.New() }, "SHA-512", false)
40 commands["RSA/sigGen/SHA2-512/224/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha512.New512_224() }, "SHA-512/224", false)
41 commands["RSA/sigGen/SHA2-512/256/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha512.New512_256() }, "SHA-512/256", false)
42 commands["RSA/sigGen/SHA3-224/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha3.New224() }, "SHA3-224", false)
43 commands["RSA/sigGen/SHA3-256/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha3.New256() }, "SHA3-256", false)
44 commands["RSA/sigGen/SHA3-384/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha3.New384() }, "SHA3-384", false)
45 commands["RSA/sigGen/SHA3-512/pkcs1v1.5"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha3.New512() }, "SHA3-512", false)
46 commands["RSA/sigGen/SHA2-512/224/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha512.New512_224() }, "SHA-512/224", true)
47 commands["RSA/sigGen/SHA2-512/256/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha512.New512_256() }, "SHA-512/256", true)
48 commands["RSA/sigGen/SHA3-224/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha3.New224() }, "SHA3-224", true)
49 commands["RSA/sigGen/SHA3-256/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha3.New256() }, "SHA3-256", true)
50 commands["RSA/sigGen/SHA3-384/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha3.New384() }, "SHA3-384", true)
51 commands["RSA/sigGen/SHA3-512/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha3.New512() }, "SHA3-512", true)
52 commands["RSA/sigGen/SHA2-224/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha256.New224() }, "SHA-224", true)
53 commands["RSA/sigGen/SHA2-256/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha256.New() }, "SHA-256", true)
54 commands["RSA/sigGen/SHA2-384/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha512.New384() }, "SHA-384", true)
55 commands["RSA/sigGen/SHA2-512/pss"] = cmdRsaSigGenSaltLenAft(func() hash.Hash { return sha512.New() }, "SHA-512", true)
56
57
58
59
60 commands["RSA/sigVer/SHA2-224/pkcs1v1.5"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha256.New224() }, "SHA-224", false)
61 commands["RSA/sigVer/SHA2-256/pkcs1v1.5"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha256.New() }, "SHA-256", false)
62 commands["RSA/sigVer/SHA2-384/pkcs1v1.5"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha512.New384() }, "SHA-384", false)
63 commands["RSA/sigVer/SHA2-512/pkcs1v1.5"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha512.New() }, "SHA-512", false)
64 commands["RSA/sigVer/SHA2-512/224/pkcs1v1.5"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha512.New512_224() }, "SHA-512/224", false)
65 commands["RSA/sigVer/SHA2-512/256/pkcs1v1.5"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha512.New512_256() }, "SHA-512/256", false)
66 commands["RSA/sigVer/SHA2-224/pss"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha256.New224() }, "SHA-224", true)
67 commands["RSA/sigVer/SHA2-256/pss"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha256.New() }, "SHA-256", true)
68 commands["RSA/sigVer/SHA2-384/pss"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha512.New384() }, "SHA-384", true)
69 commands["RSA/sigVer/SHA2-512/pss"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha512.New() }, "SHA-512", true)
70 commands["RSA/sigVer/SHA2-512/224/pss"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha512.New512_224() }, "SHA-512/224", true)
71 commands["RSA/sigVer/SHA2-512/256/pss"] = cmdRsaSigVerRandExpAft(func() hash.Hash { return sha512.New512_256() }, "SHA-512/256", true)
72
73
74
75 commands["KTS-IFC/SHA2-224/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha256.New224() })
76 commands["KTS-IFC/SHA2-256/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha256.New() })
77 commands["KTS-IFC/SHA2-384/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha512.New384() })
78 commands["KTS-IFC/SHA2-512/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha512.New() })
79 commands["KTS-IFC/SHA2-512/224/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha512.New512_224() })
80 commands["KTS-IFC/SHA2-512/256/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha512.New512_256() })
81 commands["KTS-IFC/SHA3-224/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha3.New224() })
82 commands["KTS-IFC/SHA3-256/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha3.New256() })
83 commands["KTS-IFC/SHA3-384/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha3.New384() })
84 commands["KTS-IFC/SHA3-512/responder/crt"] = cmdKtsIfcResponderRandExpCrtAft(func() hash.Hash { return sha3.New512() })
85 }
86
87 func cmdRsaKeyGenCrtAft() command {
88 return command{
89 requiredArgs: 1,
90 handler: func(args [][]byte) ([][]byte, error) {
91 bitSize := binary.LittleEndian.Uint32(args[0])
92
93 key, err := getRSAKey((int)(bitSize))
94 if err != nil {
95 return nil, fmt.Errorf("generating RSA key: %w", err)
96 }
97
98 N, e, d, P, Q, dP, dQ, qInv := key.Export()
99
100 eBytes := make([]byte, 4)
101 binary.BigEndian.PutUint32(eBytes, uint32(e))
102
103 return [][]byte{eBytes, P, Q, N, d, dP, dQ, qInv}, nil
104 },
105 }
106 }
107
108 func cmdRsaSigGenSaltLenAft(hashFunc func() hash.Hash, hashName string, pss bool) command {
109 return command{
110 requiredArgs: 3,
111 handler: func(args [][]byte) ([][]byte, error) {
112 bitSize := binary.LittleEndian.Uint32(args[0])
113 msg := args[1]
114 saltLen := binary.LittleEndian.Uint32(args[2])
115
116 key, err := getRSAKey((int)(bitSize))
117 if err != nil {
118 return nil, fmt.Errorf("generating RSA key: %w", err)
119 }
120
121 h := hashFunc()
122 h.Write(msg)
123 digest := h.Sum(nil)
124
125 var sig []byte
126 if !pss {
127 sig, err = rsa.SignPKCS1v15(key, hashName, digest)
128 if err != nil {
129 return nil, fmt.Errorf("signing RSA message: %w", err)
130 }
131 } else {
132 sig, err = rsa.SignPSS(rand.Reader, key, hashFunc(), digest, (int)(saltLen))
133 if err != nil {
134 return nil, fmt.Errorf("signing RSA message: %w", err)
135 }
136 }
137
138 N, e, _, _, _, _, _, _ := key.Export()
139 eBytes := make([]byte, 4)
140 binary.BigEndian.PutUint32(eBytes, uint32(e))
141
142 return [][]byte{N, eBytes, sig}, nil
143 },
144 }
145 }
146
147 func cmdRsaSigVerRandExpAft(hashFunc func() hash.Hash, hashName string, pss bool) command {
148 return command{
149 requiredArgs: 4,
150 handler: func(args [][]byte) ([][]byte, error) {
151 nBytes := args[0]
152 eBytes := args[1]
153 msg := args[2]
154 sig := args[3]
155
156 n, err := bigmod.NewModulus(nBytes)
157 if err != nil {
158 return nil, fmt.Errorf("invalid RSA modulus: %w", err)
159 }
160
161 h := hashFunc()
162 h.Write(msg)
163 digest := h.Sum(nil)
164
165 if len(eBytes) < 32/8 || (len(eBytes) == 32/8 && eBytes[0] < 0x80) {
166 paddedE := make([]byte, 4)
167 copy(paddedE[4-len(eBytes):], eBytes)
168 e := int(binary.BigEndian.Uint32(paddedE))
169
170 pub := &rsa.PublicKey{
171 N: n,
172 E: e,
173 }
174
175 if !pss {
176 err = rsa.VerifyPKCS1v15(pub, hashName, digest, sig)
177 } else {
178 err = rsa.VerifyPSS(pub, hashFunc(), digest, sig)
179 }
180 } else {
181 pub := &rsa.TestingOnlyLargeExponentPublicKey{
182 N: n,
183 E: eBytes,
184 }
185
186 if !pss {
187 err = rsa.TestingOnlyLargeExponentVerifyPKCS1v15(pub, hashName, digest, sig)
188 } else {
189 err = rsa.TestingOnlyLargeExponentVerifyPSS(pub, hashFunc(), digest, sig)
190 }
191 }
192
193 if err != nil {
194 return [][]byte{{0}}, nil
195 }
196
197 return [][]byte{{1}}, nil
198 },
199 }
200 }
201
202 func cmdKtsIfcResponderRandExpCrtAft(h func() hash.Hash) command {
203 return command{
204 requiredArgs: 8,
205 handler: func(args [][]byte) ([][]byte, error) {
206 nBytes := args[0]
207 eBytes := args[1]
208
209 pBytes := args[2]
210 qBytes := args[3]
211
212 dmp1Bytes := args[4]
213 dmq1Bytes := args[5]
214 iqmpBytes := args[6]
215
216 cBytes := args[7]
217
218
219
220 p, q := new(big.Int).SetBytes(pBytes), new(big.Int).SetBytes(qBytes)
221 dP, dQ := new(big.Int).SetBytes(dmp1Bytes), new(big.Int).SetBytes(dmq1Bytes)
222 pMinus1, qMinus1 := new(big.Int).Sub(p, big.NewInt(1)), new(big.Int).Sub(q, big.NewInt(1))
223 x, y := new(big.Int), new(big.Int)
224 gcd := new(big.Int).GCD(x, y, pMinus1, qMinus1)
225 diff := new(big.Int).Sub(dQ, dP)
226 if new(big.Int).Mod(diff, gcd).Sign() != 0 {
227 return nil, errors.New("inconsistent CRT parameters")
228 }
229 lcm := new(big.Int).Mul(pMinus1, qMinus1)
230 lcm.Div(lcm, gcd)
231 d := new(big.Int).Mul(x, pMinus1)
232 d.Mul(d, diff).Div(d, gcd)
233 d.Add(d, dP).Mod(d, lcm)
234
235 var dkm []byte
236 var err error
237
238 if len(eBytes) < 32/8 || (len(eBytes) == 32/8 && eBytes[0] < 0x80) {
239
240 paddedE := make([]byte, 4)
241 copy(paddedE[4-len(eBytes):], eBytes)
242 e := int(binary.BigEndian.Uint32(paddedE))
243
244 priv, err := rsa.NewPrivateKeyWithPrecomputation(nBytes, e, d.Bytes(), pBytes, qBytes, dmp1Bytes, dmq1Bytes, iqmpBytes)
245 if err != nil {
246 return nil, fmt.Errorf("failed to create private key: %v", err)
247 }
248
249 dkm, err = rsa.DecryptOAEP(h(), h(), priv, cBytes, nil)
250 } else {
251
252 priv, err := rsa.TestingOnlyNewLargeExponentPrivateKeyWithPrecomputation(nBytes, eBytes, d.Bytes(), pBytes, qBytes, dmp1Bytes, dmq1Bytes, iqmpBytes)
253 if err != nil {
254 return nil, fmt.Errorf("failed to create private key: %v", err)
255 }
256
257 dkm, err = rsa.TestingOnlyLargeExponentDecryptOAEP(h(), h(), priv, cBytes, nil)
258 }
259 if err != nil {
260 return nil, fmt.Errorf("OAEP decryption failed: %v", err)
261 }
262
263 return [][]byte{dkm}, nil
264 },
265 }
266 }
267
View as plain text