Skip to content

Commit 7f63de1

Browse files
internal/wycheproof: add RSA OAEP decryption tests
Uses only the test vectors that use the same MGF and label hashes. Change-Id: I971f78556e7b8fdbc785978dca7a613728676697 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/234917 Trust: Roland Shoemaker <roland@golang.org> Trust: Katie Hockman <katie@golang.org> Run-TryBot: Roland Shoemaker <roland@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Katie Hockman <katie@golang.org>
1 parent c90954c commit 7f63de1

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright 2020 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package wycheproof
6+
7+
import (
8+
"bytes"
9+
"crypto/rsa"
10+
"crypto/x509"
11+
"fmt"
12+
"testing"
13+
)
14+
15+
func TestRSAOAEPDecrypt(t *testing.T) {
16+
// Notes a description of the labels used in the test vectors
17+
type Notes struct {
18+
}
19+
20+
// RsaesOaepTestVector
21+
type RsaesOaepTestVector struct {
22+
23+
// A brief description of the test case
24+
Comment string `json:"comment,omitempty"`
25+
26+
// An encryption of msg
27+
Ct string `json:"ct,omitempty"`
28+
29+
// A list of flags
30+
Flags []string `json:"flags,omitempty"`
31+
32+
// The label used for the encryption
33+
Label string `json:"label,omitempty"`
34+
35+
// The encrypted message
36+
Msg string `json:"msg,omitempty"`
37+
38+
// Test result
39+
Result string `json:"result,omitempty"`
40+
41+
// Identifier of the test case
42+
TcId int `json:"tcId,omitempty"`
43+
}
44+
45+
// RsaesOaepTestGroup
46+
type RsaesOaepTestGroup struct {
47+
48+
// The private exponent
49+
D string `json:"d,omitempty"`
50+
51+
// The public exponent
52+
E string `json:"e,omitempty"`
53+
54+
// the message generating function (e.g. MGF1)
55+
Mgf string `json:"mgf,omitempty"`
56+
57+
// The hash function used for the message generating function.
58+
MgfSha string `json:"mgfSha,omitempty"`
59+
60+
// The modulus of the key
61+
N string `json:"n,omitempty"`
62+
63+
// Pem encoded private key
64+
PrivateKeyPem string `json:"privateKeyPem,omitempty"`
65+
66+
// Pkcs 8 encoded private key.
67+
PrivateKeyPkcs8 string `json:"privateKeyPkcs8,omitempty"`
68+
69+
// The hash function for hashing the label.
70+
Sha string `json:"sha,omitempty"`
71+
Tests []*RsaesOaepTestVector `json:"tests,omitempty"`
72+
Type interface{} `json:"type,omitempty"`
73+
}
74+
75+
// Root
76+
type Root struct {
77+
78+
// the primitive tested in the test file
79+
Algorithm string `json:"algorithm,omitempty"`
80+
81+
// the version of the test vectors.
82+
GeneratorVersion string `json:"generatorVersion,omitempty"`
83+
84+
// additional documentation
85+
Header []string `json:"header,omitempty"`
86+
87+
// a description of the labels used in the test vectors
88+
Notes *Notes `json:"notes,omitempty"`
89+
90+
// the number of test vectors in this test
91+
NumberOfTests int `json:"numberOfTests,omitempty"`
92+
Schema interface{} `json:"schema,omitempty"`
93+
TestGroups []*RsaesOaepTestGroup `json:"testGroups,omitempty"`
94+
}
95+
96+
// rsa.DecryptOAEP doesn't support using a different hash for the
97+
// MGF and the label, so skip all of the test vectors that use
98+
// these unbalanced constructions. rsa_oaep_misc_test.json contains
99+
// both balanced and unbalanced constructions so in that case
100+
// we just filter out any test groups where MgfSha != Sha
101+
files := []string{
102+
"rsa_oaep_2048_sha1_mgf1sha1_test.json",
103+
"rsa_oaep_2048_sha224_mgf1sha224_test.json",
104+
"rsa_oaep_2048_sha256_mgf1sha256_test.json",
105+
"rsa_oaep_2048_sha384_mgf1sha384_test.json",
106+
"rsa_oaep_2048_sha512_mgf1sha512_test.json",
107+
"rsa_oaep_3072_sha256_mgf1sha256_test.json",
108+
"rsa_oaep_3072_sha512_mgf1sha512_test.json",
109+
"rsa_oaep_4096_sha256_mgf1sha256_test.json",
110+
"rsa_oaep_4096_sha512_mgf1sha512_test.json",
111+
"rsa_oaep_misc_test.json",
112+
}
113+
114+
flagsShouldPass := map[string]bool{
115+
// rsa.DecryptOAEP happily supports small key sizes
116+
"SmallModulus": true,
117+
}
118+
119+
for _, f := range files {
120+
var root Root
121+
readTestVector(t, f, &root)
122+
for _, tg := range root.TestGroups {
123+
if tg.MgfSha != tg.Sha {
124+
continue
125+
}
126+
priv, err := x509.ParsePKCS8PrivateKey(decodeHex(tg.PrivateKeyPkcs8))
127+
if err != nil {
128+
t.Fatalf("%s failed to parse PKCS #8 private key: %s", f, err)
129+
}
130+
hash := parseHash(tg.Sha)
131+
for _, tv := range tg.Tests {
132+
t.Run(fmt.Sprintf("%s #%d", f, tv.TcId), func(t *testing.T) {
133+
wantPass := shouldPass(tv.Result, tv.Flags, flagsShouldPass)
134+
plaintext, err := rsa.DecryptOAEP(hash.New(), nil, priv.(*rsa.PrivateKey), decodeHex(tv.Ct), decodeHex(tv.Label))
135+
if wantPass {
136+
if err != nil {
137+
t.Fatalf("comment: %s, expected success: %s", tv.Comment, err)
138+
}
139+
if !bytes.Equal(plaintext, decodeHex(tv.Msg)) {
140+
t.Errorf("comment: %s, unexpected plaintext: got %x, want %s", tv.Comment, plaintext, tv.Msg)
141+
}
142+
} else if err == nil {
143+
t.Errorf("comment: %s, expected failure", tv.Comment)
144+
}
145+
})
146+
}
147+
}
148+
}
149+
}

0 commit comments

Comments
 (0)