Source file
src/crypto/rsa/pss_test.go
1
2
3
4
5 package rsa_test
6
7 import (
8 "bufio"
9 "compress/bzip2"
10 "crypto"
11 "crypto/internal/fips140"
12 "crypto/rand"
13 . "crypto/rsa"
14 "crypto/sha256"
15 "crypto/sha512"
16 "encoding/hex"
17 "math/big"
18 "os"
19 "strconv"
20 "strings"
21 "testing"
22 )
23
24
25
26 func TestPSSGolden(t *testing.T) {
27 inFile, err := os.Open("testdata/pss-vect.txt.bz2")
28 if err != nil {
29 t.Fatalf("Failed to open input file: %s", err)
30 }
31 defer inFile.Close()
32
33
34
35
36
37 const newKeyMarker = "START NEW KEY"
38 const newSignatureMarker = "START NEW SIGNATURE"
39
40 values := make(chan string)
41
42 go func() {
43 defer close(values)
44 scanner := bufio.NewScanner(bzip2.NewReader(inFile))
45 var partialValue string
46 lastWasValue := true
47
48 for scanner.Scan() {
49 line := scanner.Text()
50 switch {
51 case len(line) == 0:
52 if len(partialValue) > 0 {
53 values <- strings.ReplaceAll(partialValue, " ", "")
54 partialValue = ""
55 lastWasValue = true
56 }
57 continue
58 case strings.HasPrefix(line, "# ======") && lastWasValue:
59 values <- newKeyMarker
60 lastWasValue = false
61 case strings.HasPrefix(line, "# ------") && lastWasValue:
62 values <- newSignatureMarker
63 lastWasValue = false
64 case strings.HasPrefix(line, "#"):
65 continue
66 default:
67 partialValue += line
68 }
69 }
70 if err := scanner.Err(); err != nil {
71 panic(err)
72 }
73 }()
74
75 var key *PublicKey
76 var hashed []byte
77 hash := crypto.SHA1
78 h := hash.New()
79 opts := &PSSOptions{
80 SaltLength: PSSSaltLengthEqualsHash,
81 }
82
83 for marker := range values {
84 switch marker {
85 case newKeyMarker:
86 key = new(PublicKey)
87 nHex, ok := <-values
88 if !ok {
89 continue
90 }
91 key.N = bigFromHex(nHex)
92 key.E = intFromHex(<-values)
93
94 for i := 0; i < 6; i++ {
95 <-values
96 }
97 case newSignatureMarker:
98 msg := fromHex(<-values)
99 <-values
100 sig := fromHex(<-values)
101
102 h.Reset()
103 h.Write(msg)
104 hashed = h.Sum(hashed[:0])
105
106 if err := VerifyPSS(key, hash, hashed, sig, opts); err != nil {
107 t.Error(err)
108 }
109 default:
110 t.Fatalf("unknown marker: %s", marker)
111 }
112 }
113 }
114
115
116
117 func TestPSSOpenSSL(t *testing.T) {
118 t.Setenv("GODEBUG", "rsa1024min=0")
119
120 hash := crypto.SHA256
121 h := hash.New()
122 h.Write([]byte("testing"))
123 hashed := h.Sum(nil)
124
125
126 sig := []byte{
127 0x95, 0x59, 0x6f, 0xd3, 0x10, 0xa2, 0xe7, 0xa2, 0x92, 0x9d,
128 0x4a, 0x07, 0x2e, 0x2b, 0x27, 0xcc, 0x06, 0xc2, 0x87, 0x2c,
129 0x52, 0xf0, 0x4a, 0xcc, 0x05, 0x94, 0xf2, 0xc3, 0x2e, 0x20,
130 0xd7, 0x3e, 0x66, 0x62, 0xb5, 0x95, 0x2b, 0xa3, 0x93, 0x9a,
131 0x66, 0x64, 0x25, 0xe0, 0x74, 0x66, 0x8c, 0x3e, 0x92, 0xeb,
132 0xc6, 0xe6, 0xc0, 0x44, 0xf3, 0xb4, 0xb4, 0x2e, 0x8c, 0x66,
133 0x0a, 0x37, 0x9c, 0x69,
134 }
135
136 if err := VerifyPSS(&test512Key.PublicKey, hash, hashed, sig, nil); err != nil {
137 t.Error(err)
138 }
139 }
140
141 func TestPSSNilOpts(t *testing.T) {
142 hash := crypto.SHA256
143 h := hash.New()
144 h.Write([]byte("testing"))
145 hashed := h.Sum(nil)
146
147 SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, nil)
148 }
149
150 func TestPSSSigning(t *testing.T) {
151 var saltLengthCombinations = []struct {
152 signSaltLength, verifySaltLength int
153 good, fipsGood bool
154 }{
155 {PSSSaltLengthAuto, PSSSaltLengthAuto, true, true},
156 {PSSSaltLengthEqualsHash, PSSSaltLengthAuto, true, true},
157 {PSSSaltLengthEqualsHash, PSSSaltLengthEqualsHash, true, true},
158 {PSSSaltLengthEqualsHash, 8, false, false},
159 {8, 8, true, true},
160 {8, PSSSaltLengthAuto, true, true},
161 {42, PSSSaltLengthAuto, true, true},
162
163 {PSSSaltLengthAuto, PSSSaltLengthEqualsHash, false, true},
164 {PSSSaltLengthAuto, 106, true, false},
165 {PSSSaltLengthAuto, 20, false, true},
166 {PSSSaltLengthAuto, -2, false, false},
167 }
168
169 hash := crypto.SHA1
170 h := hash.New()
171 h.Write([]byte("testing"))
172 hashed := h.Sum(nil)
173 var opts PSSOptions
174
175 for i, test := range saltLengthCombinations {
176 opts.SaltLength = test.signSaltLength
177 sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts)
178 if err != nil {
179 t.Errorf("#%d: error while signing: %s", i, err)
180 continue
181 }
182
183 opts.SaltLength = test.verifySaltLength
184 err = VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, &opts)
185 good := test.good
186 if fips140.Enabled {
187 good = test.fipsGood
188 }
189 if (err == nil) != good {
190 t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err)
191 }
192 }
193 }
194
195 func TestPSS513(t *testing.T) {
196
197
198
199 t.Setenv("GODEBUG", "rsa1024min=0")
200 key, err := GenerateKey(rand.Reader, 513)
201 if err != nil {
202 t.Fatal(err)
203 }
204 digest := sha256.Sum256([]byte("message"))
205 signature, err := key.Sign(rand.Reader, digest[:], &PSSOptions{
206 SaltLength: PSSSaltLengthAuto,
207 Hash: crypto.SHA256,
208 })
209 if err != nil {
210 t.Fatal(err)
211 }
212 err = VerifyPSS(&key.PublicKey, crypto.SHA256, digest[:], signature, nil)
213 if err != nil {
214 t.Error(err)
215 }
216 }
217
218 func bigFromHex(hex string) *big.Int {
219 n, ok := new(big.Int).SetString(hex, 16)
220 if !ok {
221 panic("bad hex: " + hex)
222 }
223 return n
224 }
225
226 func intFromHex(hex string) int {
227 i, err := strconv.ParseInt(hex, 16, 32)
228 if err != nil {
229 panic(err)
230 }
231 return int(i)
232 }
233
234 func fromHex(hexStr string) []byte {
235 s, err := hex.DecodeString(hexStr)
236 if err != nil {
237 panic(err)
238 }
239 return s
240 }
241
242 func TestInvalidPSSSaltLength(t *testing.T) {
243 t.Setenv("GODEBUG", "rsa1024min=0")
244 key, err := GenerateKey(rand.Reader, 245)
245 if err != nil {
246 t.Fatal(err)
247 }
248
249 digest := sha256.Sum256([]byte("message"))
250 if _, err := SignPSS(rand.Reader, key, crypto.SHA256, digest[:], &PSSOptions{
251 SaltLength: -2,
252 Hash: crypto.SHA256,
253 }); err.Error() != "crypto/rsa: invalid PSS salt length" {
254 t.Fatalf("SignPSS unexpected error: got %v, want %v", err, "crypto/rsa: invalid PSS salt length")
255 }
256
257
258
259 if err := VerifyPSS(&key.PublicKey, crypto.SHA256, []byte{1, 2, 3}, make([]byte, 31), &PSSOptions{
260 SaltLength: -2,
261 }); err == nil {
262 t.Fatal("VerifyPSS unexpected success")
263 }
264 }
265
266 func TestHashOverride(t *testing.T) {
267 digest := sha512.Sum512([]byte("message"))
268
269 sig, err := SignPSS(rand.Reader, test2048Key, crypto.SHA256, digest[:], &PSSOptions{Hash: crypto.SHA512})
270 if err != nil {
271 t.Fatalf("SignPSS unexpected error: got %v, want nil", err)
272 }
273
274
275 if err := VerifyPSS(&test2048Key.PublicKey, crypto.SHA512, digest[:], sig, &PSSOptions{Hash: crypto.SHA256}); err != nil {
276 t.Fatalf("VerifyPSS unexpected error: got %v, want nil", err)
277 }
278 }
279
View as plain text