1// Copyright 2020 The BoringSSL Authors 2// 3// Permission to use, copy, modify, and/or distribute this software for any 4// purpose with or without fee is hereby granted, provided that the above 5// copyright notice and this permission notice appear in all copies. 6// 7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15package subprocess 16 17import ( 18 "encoding/hex" 19 "encoding/json" 20 "fmt" 21) 22 23// See https://pages.nist.gov/ACVP/draft-celi-acvp-rsa.html#name-test-vectors 24// although, at the time of writing, that spec doesn't match what the NIST demo 25// server actually produces. This code matches the server. 26 27type rsaTestVectorSet struct { 28 Mode string `json:"mode"` 29} 30 31type rsaKeyGenTestVectorSet struct { 32 Groups []rsaKeyGenGroup `json:"testGroups"` 33} 34 35type rsaKeyGenGroup struct { 36 ID uint64 `json:"tgId"` 37 Type string `json:"testType"` 38 ModulusBits uint32 `json:"modulo"` 39 Tests []rsaKeyGenTest `json:"tests"` 40} 41 42type rsaKeyGenTest struct { 43 ID uint64 `json:"tcId"` 44} 45 46type rsaKeyGenTestGroupResponse struct { 47 ID uint64 `json:"tgId"` 48 Tests []rsaKeyGenTestResponse `json:"tests"` 49} 50 51type rsaKeyGenTestResponse struct { 52 ID uint64 `json:"tcId"` 53 E string `json:"e"` 54 P string `json:"p"` 55 Q string `json:"q"` 56 N string `json:"n"` 57 D string `json:"d"` 58} 59 60type rsaSigGenTestVectorSet struct { 61 Groups []rsaSigGenGroup `json:"testGroups"` 62} 63 64type rsaSigGenGroup struct { 65 ID uint64 `json:"tgId"` 66 Type string `json:"testType"` 67 SigType string `json:"sigType"` 68 ModulusBits uint32 `json:"modulo"` 69 Hash string `json:"hashAlg"` 70 Tests []rsaSigGenTest `json:"tests"` 71} 72 73type rsaSigGenTest struct { 74 ID uint64 `json:"tcId"` 75 MessageHex string `json:"message"` 76} 77 78type rsaSigGenTestGroupResponse struct { 79 ID uint64 `json:"tgId"` 80 N string `json:"n"` 81 E string `json:"e"` 82 Tests []rsaSigGenTestResponse `json:"tests"` 83} 84 85type rsaSigGenTestResponse struct { 86 ID uint64 `json:"tcId"` 87 Sig string `json:"signature"` 88} 89 90type rsaSigVerTestVectorSet struct { 91 Groups []rsaSigVerGroup `json:"testGroups"` 92} 93 94type rsaSigVerGroup struct { 95 ID uint64 `json:"tgId"` 96 Type string `json:"testType"` 97 SigType string `json:"sigType"` 98 Hash string `json:"hashAlg"` 99 N string `json:"n"` 100 E string `json:"e"` 101 Tests []rsaSigVerTest `json:"tests"` 102} 103 104type rsaSigVerTest struct { 105 ID uint64 `json:"tcId"` 106 MessageHex string `json:"message"` 107 SignatureHex string `json:"signature"` 108} 109 110type rsaSigVerTestGroupResponse struct { 111 ID uint64 `json:"tgId"` 112 Tests []rsaSigVerTestResponse `json:"tests"` 113} 114 115type rsaSigVerTestResponse struct { 116 ID uint64 `json:"tcId"` 117 Passed bool `json:"testPassed"` 118} 119 120func processKeyGen(vectorSet []byte, m Transactable) (any, error) { 121 var parsed rsaKeyGenTestVectorSet 122 if err := json.Unmarshal(vectorSet, &parsed); err != nil { 123 return nil, err 124 } 125 126 var ret []rsaKeyGenTestGroupResponse 127 128 for _, group := range parsed.Groups { 129 group := group 130 131 // GDT means "Generated data test", i.e. "please generate an RSA key". 132 const expectedType = "GDT" 133 if group.Type != expectedType { 134 return nil, fmt.Errorf("RSA KeyGen test group has type %q, but only generation tests (%q) are supported", group.Type, expectedType) 135 } 136 137 response := rsaKeyGenTestGroupResponse{ 138 ID: group.ID, 139 } 140 141 for _, test := range group.Tests { 142 test := test 143 144 m.TransactAsync("RSA/keyGen", 5, [][]byte{uint32le(group.ModulusBits)}, func(result [][]byte) error { 145 response.Tests = append(response.Tests, rsaKeyGenTestResponse{ 146 ID: test.ID, 147 E: hex.EncodeToString(result[0]), 148 P: hex.EncodeToString(result[1]), 149 Q: hex.EncodeToString(result[2]), 150 N: hex.EncodeToString(result[3]), 151 D: hex.EncodeToString(result[4]), 152 }) 153 return nil 154 }) 155 } 156 157 m.Barrier(func() { 158 ret = append(ret, response) 159 }) 160 } 161 162 if err := m.Flush(); err != nil { 163 return nil, err 164 } 165 166 return ret, nil 167} 168 169func processSigGen(vectorSet []byte, m Transactable) (any, error) { 170 var parsed rsaSigGenTestVectorSet 171 if err := json.Unmarshal(vectorSet, &parsed); err != nil { 172 return nil, err 173 } 174 175 var ret []rsaSigGenTestGroupResponse 176 177 for _, group := range parsed.Groups { 178 group := group 179 180 // GDT means "Generated data test", i.e. "please generate an RSA signature". 181 const expectedType = "GDT" 182 if group.Type != expectedType { 183 return nil, fmt.Errorf("RSA SigGen test group has type %q, but only generation tests (%q) are supported", group.Type, expectedType) 184 } 185 186 response := rsaSigGenTestGroupResponse{ 187 ID: group.ID, 188 } 189 190 operation := "RSA/sigGen/" + group.Hash + "/" + group.SigType 191 192 for _, test := range group.Tests { 193 test := test 194 195 msg, err := hex.DecodeString(test.MessageHex) 196 if err != nil { 197 return nil, fmt.Errorf("test case %d/%d contains invalid hex: %s", group.ID, test.ID, err) 198 } 199 200 m.TransactAsync(operation, 3, [][]byte{uint32le(group.ModulusBits), msg}, func(result [][]byte) error { 201 if len(response.N) == 0 { 202 response.N = hex.EncodeToString(result[0]) 203 response.E = hex.EncodeToString(result[1]) 204 } else if response.N != hex.EncodeToString(result[0]) { 205 return fmt.Errorf("module wrapper returned different RSA keys for the same SigGen configuration") 206 } 207 208 response.Tests = append(response.Tests, rsaSigGenTestResponse{ 209 ID: test.ID, 210 Sig: hex.EncodeToString(result[2]), 211 }) 212 return nil 213 }) 214 } 215 216 m.Barrier(func() { 217 ret = append(ret, response) 218 }) 219 } 220 221 if err := m.Flush(); err != nil { 222 return nil, err 223 } 224 225 return ret, nil 226} 227 228func processSigVer(vectorSet []byte, m Transactable) (any, error) { 229 var parsed rsaSigVerTestVectorSet 230 if err := json.Unmarshal(vectorSet, &parsed); err != nil { 231 return nil, err 232 } 233 234 var ret []rsaSigVerTestGroupResponse 235 236 for _, group := range parsed.Groups { 237 group := group 238 239 // GDT means "Generated data test", which makes no sense in this context. 240 const expectedType = "GDT" 241 if group.Type != expectedType { 242 return nil, fmt.Errorf("RSA SigVer test group has type %q, but only 'generation' tests (%q) are supported", group.Type, expectedType) 243 } 244 245 n, err := hex.DecodeString(group.N) 246 if err != nil { 247 return nil, fmt.Errorf("test group %d contains invalid hex: %s", group.ID, err) 248 } 249 e, err := hex.DecodeString(group.E) 250 if err != nil { 251 return nil, fmt.Errorf("test group %d contains invalid hex: %s", group.ID, err) 252 } 253 254 response := rsaSigVerTestGroupResponse{ 255 ID: group.ID, 256 } 257 258 operation := "RSA/sigVer/" + group.Hash + "/" + group.SigType 259 260 for _, test := range group.Tests { 261 test := test 262 msg, err := hex.DecodeString(test.MessageHex) 263 if err != nil { 264 return nil, fmt.Errorf("test case %d/%d contains invalid hex: %s", group.ID, test.ID, err) 265 } 266 sig, err := hex.DecodeString(test.SignatureHex) 267 if err != nil { 268 return nil, fmt.Errorf("test case %d/%d contains invalid hex: %s", group.ID, test.ID, err) 269 } 270 271 m.TransactAsync(operation, 1, [][]byte{n, e, msg, sig}, func(result [][]byte) error { 272 response.Tests = append(response.Tests, rsaSigVerTestResponse{ 273 ID: test.ID, 274 Passed: len(result[0]) == 1 && result[0][0] == 1, 275 }) 276 return nil 277 }) 278 } 279 280 m.Barrier(func() { 281 ret = append(ret, response) 282 }) 283 } 284 285 if err := m.Flush(); err != nil { 286 return nil, err 287 } 288 289 return ret, nil 290} 291 292type rsa struct{} 293 294func (*rsa) Process(vectorSet []byte, m Transactable) (any, error) { 295 var parsed rsaTestVectorSet 296 if err := json.Unmarshal(vectorSet, &parsed); err != nil { 297 return nil, err 298 } 299 300 switch parsed.Mode { 301 case "keyGen": 302 return processKeyGen(vectorSet, m) 303 case "sigGen": 304 return processSigGen(vectorSet, m) 305 case "sigVer": 306 return processSigVer(vectorSet, m) 307 default: 308 return nil, fmt.Errorf("Unknown RSA mode %q", parsed.Mode) 309 } 310} 311