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