acvp: RSA signature verification tests.

Change-Id: I8697230d4feb3bc5308905aa8981087b0f080555
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/43626
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
chromium-5359
Adam Langley 4 years ago committed by CQ bot account: commit-bot@chromium.org
parent e44d977c5e
commit 777e1ff3b1
  1. 89
      util/fipstools/acvp/acvptool/subprocess/rsa.go
  2. 182
      util/fipstools/acvp/modulewrapper/modulewrapper.cc

@ -87,6 +87,36 @@ type rsaSigGenTestResponse struct {
Sig string `json:"signature"` Sig string `json:"signature"`
} }
type rsaSigVerTestVectorSet struct {
Groups []rsaSigVerGroup `json:"testGroups"`
}
type rsaSigVerGroup struct {
ID uint64 `json:"tgId"`
Type string `json:"testType"`
SigType string `json:"sigType"`
Hash string `json:"hashAlg"`
N string `json:"n"`
E string `json:"e"`
Tests []rsaSigVerTest `json:"tests"`
}
type rsaSigVerTest struct {
ID uint64 `json:"tcId"`
MessageHex string `json:"message"`
SignatureHex string `json:"signature"`
}
type rsaSigVerTestGroupResponse struct {
ID uint64 `json:"tgId"`
Tests []rsaSigVerTestResponse `json:"tests"`
}
type rsaSigVerTestResponse struct {
ID uint64 `json:"tcId"`
Passed bool `json:"testPassed"`
}
func processKeyGen(vectorSet []byte, m Transactable) (interface{}, error) { func processKeyGen(vectorSet []byte, m Transactable) (interface{}, error) {
var parsed rsaKeyGenTestVectorSet var parsed rsaKeyGenTestVectorSet
if err := json.Unmarshal(vectorSet, &parsed); err != nil { if err := json.Unmarshal(vectorSet, &parsed); err != nil {
@ -179,6 +209,63 @@ func processSigGen(vectorSet []byte, m Transactable) (interface{}, error) {
return ret, nil return ret, nil
} }
func processSigVer(vectorSet []byte, m Transactable) (interface{}, error) {
var parsed rsaSigVerTestVectorSet
if err := json.Unmarshal(vectorSet, &parsed); err != nil {
return nil, err
}
var ret []rsaSigVerTestGroupResponse
for _, group := range parsed.Groups {
// GDT means "Generated data test", which makes no sense in this context.
const expectedType = "GDT"
if group.Type != expectedType {
return nil, fmt.Errorf("RSA SigVer test group has type %q, but only 'generation' tests (%q) are supported", group.Type, expectedType)
}
n, err := hex.DecodeString(group.N)
if err != nil {
return nil, fmt.Errorf("test group %d contains invalid hex: %s", group.ID, err)
}
e, err := hex.DecodeString(group.E)
if err != nil {
return nil, fmt.Errorf("test group %d contains invalid hex: %s", group.ID, err)
}
response := rsaSigVerTestGroupResponse{
ID: group.ID,
}
operation := "RSA/sigVer/" + group.Hash + "/" + group.SigType
for _, test := range group.Tests {
msg, err := hex.DecodeString(test.MessageHex)
if err != nil {
return nil, fmt.Errorf("test case %d/%d contains invalid hex: %s", group.ID, test.ID, err)
}
sig, err := hex.DecodeString(test.SignatureHex)
if err != nil {
return nil, fmt.Errorf("test case %d/%d contains invalid hex: %s", group.ID, test.ID, err)
}
results, err := m.Transact(operation, 1, n, e, msg, sig)
if err != nil {
return nil, err
}
response.Tests = append(response.Tests, rsaSigVerTestResponse{
ID: test.ID,
Passed: len(results[0]) == 1 && results[0][0] == 1,
})
}
ret = append(ret, response)
}
return ret, nil
}
type rsa struct{} type rsa struct{}
func (*rsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { func (*rsa) Process(vectorSet []byte, m Transactable) (interface{}, error) {
@ -192,6 +279,8 @@ func (*rsa) Process(vectorSet []byte, m Transactable) (interface{}, error) {
return processKeyGen(vectorSet, m) return processKeyGen(vectorSet, m)
case "sigGen": case "sigGen":
return processSigGen(vectorSet, m) return processSigGen(vectorSet, m)
case "sigVer":
return processSigVer(vectorSet, m)
default: default:
return nil, fmt.Errorf("Unknown RSA mode %q", parsed.Mode) return nil, fmt.Errorf("Unknown RSA mode %q", parsed.Mode)
} }

@ -33,6 +33,7 @@
#include <openssl/ec.h> #include <openssl/ec.h>
#include <openssl/ec_key.h> #include <openssl/ec_key.h>
#include <openssl/ecdsa.h> #include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
#include <openssl/obj.h> #include <openssl/obj.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
@ -542,6 +543,141 @@ static bool GetConfig(const Span<const uint8_t> args[]) {
}] }]
}] }]
}, },
{
"algorithm": "RSA",
"mode": "sigVer",
"revision": "FIPS186-4",
"pubExpMode": "fixed",
"fixedPubExp": "010001",
"capabilities": [{
"sigType": "pkcs1v1.5",
"properties": [{
"modulo": 1024,
"hashPair": [{
"hashAlg": "SHA2-224"
}, {
"hashAlg": "SHA2-256"
}, {
"hashAlg": "SHA2-384"
}, {
"hashAlg": "SHA2-512"
}, {
"hashAlg": "SHA-1"
}]
}]
},{
"sigType": "pkcs1v1.5",
"properties": [{
"modulo": 2048,
"hashPair": [{
"hashAlg": "SHA2-224"
}, {
"hashAlg": "SHA2-256"
}, {
"hashAlg": "SHA2-384"
}, {
"hashAlg": "SHA2-512"
}, {
"hashAlg": "SHA-1"
}]
}]
},{
"sigType": "pkcs1v1.5",
"properties": [{
"modulo": 3072,
"hashPair": [{
"hashAlg": "SHA2-224"
}, {
"hashAlg": "SHA2-256"
}, {
"hashAlg": "SHA2-384"
}, {
"hashAlg": "SHA2-512"
}, {
"hashAlg": "SHA-1"
}]
}]
},{
"sigType": "pkcs1v1.5",
"properties": [{
"modulo": 4096,
"hashPair": [{
"hashAlg": "SHA2-224"
}, {
"hashAlg": "SHA2-256"
}, {
"hashAlg": "SHA2-384"
}, {
"hashAlg": "SHA2-512"
}, {
"hashAlg": "SHA-1"
}]
}]
},{
"sigType": "pss",
"properties": [{
"modulo": 2048,
"hashPair": [{
"hashAlg": "SHA2-224",
"saltLen": 28
}, {
"hashAlg": "SHA2-256",
"saltLen": 32
}, {
"hashAlg": "SHA2-384",
"saltLen": 48
}, {
"hashAlg": "SHA2-512",
"saltLen": 64
}, {
"hashAlg": "SHA-1",
"saltLen": 20
}]
}]
},{
"sigType": "pss",
"properties": [{
"modulo": 3072,
"hashPair": [{
"hashAlg": "SHA2-224",
"saltLen": 28
}, {
"hashAlg": "SHA2-256",
"saltLen": 32
}, {
"hashAlg": "SHA2-384",
"saltLen": 48
}, {
"hashAlg": "SHA2-512",
"saltLen": 64
}, {
"hashAlg": "SHA-1",
"saltLen": 20
}]
}]
},{
"sigType": "pss",
"properties": [{
"modulo": 4096,
"hashPair": [{
"hashAlg": "SHA2-224",
"saltLen": 28
}, {
"hashAlg": "SHA2-256",
"saltLen": 32
}, {
"hashAlg": "SHA2-384",
"saltLen": 48
}, {
"hashAlg": "SHA2-512",
"saltLen": 64
}, {
"hashAlg": "SHA-1",
"saltLen": 20
}]
}]
}]
},
{ {
"algorithm": "CMAC-AES", "algorithm": "CMAC-AES",
"revision": "1.0", "revision": "1.0",
@ -1238,6 +1374,42 @@ static bool RSASigGen(const Span<const uint8_t> args[]) {
BIGNUMBytes(RSA_get0_e(key)), sig); BIGNUMBytes(RSA_get0_e(key)), sig);
} }
template<const EVP_MD *(MDFunc)(), bool UsePSS>
static bool RSASigVer(const Span<const uint8_t> args[]) {
const Span<const uint8_t> n_bytes = args[0];
const Span<const uint8_t> e_bytes = args[1];
const Span<const uint8_t> msg = args[2];
const Span<const uint8_t> sig = args[3];
BIGNUM *n = BN_new();
BIGNUM *e = BN_new();
bssl::UniquePtr<RSA> key(RSA_new());
if (!BN_bin2bn(n_bytes.data(), n_bytes.size(), n) ||
!BN_bin2bn(e_bytes.data(), e_bytes.size(), e) ||
!RSA_set0_key(key.get(), n, e, /*d=*/nullptr)) {
return false;
}
const EVP_MD *const md = MDFunc();
uint8_t digest_buf[EVP_MAX_MD_SIZE];
unsigned digest_len;
if (!EVP_Digest(msg.data(), msg.size(), digest_buf, &digest_len, md, NULL)) {
return false;
}
uint8_t ok;
if (UsePSS) {
ok = RSA_verify_pss_mgf1(key.get(), digest_buf, digest_len, md, md, -1,
sig.data(), sig.size());
} else {
ok = RSA_verify(EVP_MD_type(md), digest_buf, digest_len, sig.data(),
sig.size(), key.get());
}
ERR_clear_error();
return WriteReply(STDOUT_FILENO, Span<const uint8_t>(&ok, 1));
}
static constexpr struct { static constexpr struct {
const char name[kMaxNameLength + 1]; const char name[kMaxNameLength + 1];
uint8_t expected_args; uint8_t expected_args;
@ -1289,6 +1461,16 @@ static constexpr struct {
{"RSA/sigGen/SHA2-384/pss", 2, RSASigGen<EVP_sha384, true>}, {"RSA/sigGen/SHA2-384/pss", 2, RSASigGen<EVP_sha384, true>},
{"RSA/sigGen/SHA2-512/pss", 2, RSASigGen<EVP_sha512, true>}, {"RSA/sigGen/SHA2-512/pss", 2, RSASigGen<EVP_sha512, true>},
{"RSA/sigGen/SHA-1/pss", 2, RSASigGen<EVP_sha1, true>}, {"RSA/sigGen/SHA-1/pss", 2, RSASigGen<EVP_sha1, true>},
{"RSA/sigVer/SHA2-224/pkcs1v1.5", 4, RSASigVer<EVP_sha224, false>},
{"RSA/sigVer/SHA2-256/pkcs1v1.5", 4, RSASigVer<EVP_sha256, false>},
{"RSA/sigVer/SHA2-384/pkcs1v1.5", 4, RSASigVer<EVP_sha384, false>},
{"RSA/sigVer/SHA2-512/pkcs1v1.5", 4, RSASigVer<EVP_sha512, false>},
{"RSA/sigVer/SHA-1/pkcs1v1.5", 4, RSASigVer<EVP_sha1, false>},
{"RSA/sigVer/SHA2-224/pss", 4, RSASigVer<EVP_sha224, true>},
{"RSA/sigVer/SHA2-256/pss", 4, RSASigVer<EVP_sha256, true>},
{"RSA/sigVer/SHA2-384/pss", 4, RSASigVer<EVP_sha384, true>},
{"RSA/sigVer/SHA2-512/pss", 4, RSASigVer<EVP_sha512, true>},
{"RSA/sigVer/SHA-1/pss", 4, RSASigVer<EVP_sha1, true>},
}; };
int main() { int main() {

Loading…
Cancel
Save