Mirror of BoringSSL (grpc依赖)
https://boringssl.googlesource.com/boringssl
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
287 lines
7.9 KiB
287 lines
7.9 KiB
// Copyright (c) 2020, Google Inc. |
|
// |
|
// Permission to use, copy, modify, and/or distribute this software for any |
|
// purpose with or without fee is hereby granted, provided that the above |
|
// copyright notice and this permission notice appear in all copies. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
|
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
|
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
|
|
package subprocess |
|
|
|
import ( |
|
"encoding/hex" |
|
"encoding/json" |
|
"fmt" |
|
) |
|
|
|
// See https://pages.nist.gov/ACVP/draft-celi-acvp-rsa.html#name-test-vectors |
|
// although, at the time of writing, that spec doesn't match what the NIST demo |
|
// server actually produces. This code matches the server. |
|
|
|
type rsaTestVectorSet struct { |
|
Mode string `json:"mode"` |
|
} |
|
|
|
type rsaKeyGenTestVectorSet struct { |
|
Groups []rsaKeyGenGroup `json:"testGroups"` |
|
} |
|
|
|
type rsaKeyGenGroup struct { |
|
ID uint64 `json:"tgId"` |
|
Type string `json:"testType"` |
|
ModulusBits uint32 `json:"modulo"` |
|
Tests []rsaKeyGenTest `json:"tests"` |
|
} |
|
|
|
type rsaKeyGenTest struct { |
|
ID uint64 `json:"tcId"` |
|
} |
|
|
|
type rsaKeyGenTestGroupResponse struct { |
|
ID uint64 `json:"tgId"` |
|
Tests []rsaKeyGenTestResponse `json:"tests"` |
|
} |
|
|
|
type rsaKeyGenTestResponse struct { |
|
ID uint64 `json:"tcId"` |
|
E string `json:"e"` |
|
P string `json:"p"` |
|
Q string `json:"q"` |
|
N string `json:"n"` |
|
D string `json:"d"` |
|
} |
|
|
|
type rsaSigGenTestVectorSet struct { |
|
Groups []rsaSigGenGroup `json:"testGroups"` |
|
} |
|
|
|
type rsaSigGenGroup struct { |
|
ID uint64 `json:"tgId"` |
|
Type string `json:"testType"` |
|
SigType string `json:"sigType"` |
|
ModulusBits uint32 `json:"modulo"` |
|
Hash string `json:"hashAlg"` |
|
Tests []rsaSigGenTest `json:"tests"` |
|
} |
|
|
|
type rsaSigGenTest struct { |
|
ID uint64 `json:"tcId"` |
|
MessageHex string `json:"message"` |
|
} |
|
|
|
type rsaSigGenTestGroupResponse struct { |
|
ID uint64 `json:"tgId"` |
|
N string `json:"n"` |
|
E string `json:"e"` |
|
Tests []rsaSigGenTestResponse `json:"tests"` |
|
} |
|
|
|
type rsaSigGenTestResponse struct { |
|
ID uint64 `json:"tcId"` |
|
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) { |
|
var parsed rsaKeyGenTestVectorSet |
|
if err := json.Unmarshal(vectorSet, &parsed); err != nil { |
|
return nil, err |
|
} |
|
|
|
var ret []rsaKeyGenTestGroupResponse |
|
|
|
for _, group := range parsed.Groups { |
|
// GDT means "Generated data test", i.e. "please generate an RSA key". |
|
const expectedType = "GDT" |
|
if group.Type != expectedType { |
|
return nil, fmt.Errorf("RSA KeyGen test group has type %q, but only generation tests (%q) are supported", group.Type, expectedType) |
|
} |
|
|
|
response := rsaKeyGenTestGroupResponse{ |
|
ID: group.ID, |
|
} |
|
|
|
for _, test := range group.Tests { |
|
results, err := m.Transact("RSA/keyGen", 5, uint32le(group.ModulusBits)) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
response.Tests = append(response.Tests, rsaKeyGenTestResponse{ |
|
ID: test.ID, |
|
E: hex.EncodeToString(results[0]), |
|
P: hex.EncodeToString(results[1]), |
|
Q: hex.EncodeToString(results[2]), |
|
N: hex.EncodeToString(results[3]), |
|
D: hex.EncodeToString(results[4]), |
|
}) |
|
} |
|
|
|
ret = append(ret, response) |
|
} |
|
|
|
return ret, nil |
|
} |
|
|
|
func processSigGen(vectorSet []byte, m Transactable) (interface{}, error) { |
|
var parsed rsaSigGenTestVectorSet |
|
if err := json.Unmarshal(vectorSet, &parsed); err != nil { |
|
return nil, err |
|
} |
|
|
|
var ret []rsaSigGenTestGroupResponse |
|
|
|
for _, group := range parsed.Groups { |
|
// GDT means "Generated data test", i.e. "please generate an RSA signature". |
|
const expectedType = "GDT" |
|
if group.Type != expectedType { |
|
return nil, fmt.Errorf("RSA SigGen test group has type %q, but only generation tests (%q) are supported", group.Type, expectedType) |
|
} |
|
|
|
response := rsaSigGenTestGroupResponse{ |
|
ID: group.ID, |
|
} |
|
|
|
operation := "RSA/sigGen/" + 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) |
|
} |
|
|
|
results, err := m.Transact(operation, 3, uint32le(group.ModulusBits), msg) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
if len(response.N) == 0 { |
|
response.N = hex.EncodeToString(results[0]) |
|
response.E = hex.EncodeToString(results[1]) |
|
} else if response.N != hex.EncodeToString(results[0]) { |
|
return nil, fmt.Errorf("module wrapper returned different RSA keys for the same SigGen configuration") |
|
} |
|
|
|
response.Tests = append(response.Tests, rsaSigGenTestResponse{ |
|
ID: test.ID, |
|
Sig: hex.EncodeToString(results[2]), |
|
}) |
|
} |
|
|
|
ret = append(ret, response) |
|
} |
|
|
|
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{} |
|
|
|
func (*rsa) Process(vectorSet []byte, m Transactable) (interface{}, error) { |
|
var parsed rsaTestVectorSet |
|
if err := json.Unmarshal(vectorSet, &parsed); err != nil { |
|
return nil, err |
|
} |
|
|
|
switch parsed.Mode { |
|
case "keyGen": |
|
return processKeyGen(vectorSet, m) |
|
case "sigGen": |
|
return processSigGen(vectorSet, m) |
|
case "sigVer": |
|
return processSigVer(vectorSet, m) |
|
default: |
|
return nil, fmt.Errorf("Unknown RSA mode %q", parsed.Mode) |
|
} |
|
}
|
|
|