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.
304 lines
8.6 KiB
304 lines
8.6 KiB
/* Copyright (c) 2018, 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. */ |
|
|
|
// convert_wycheproof.go converts Wycheproof test vectors into a format more |
|
// easily consumed by BoringSSL. |
|
package main |
|
|
|
import ( |
|
"encoding/json" |
|
"fmt" |
|
"io" |
|
"io/ioutil" |
|
"os" |
|
"sort" |
|
"strings" |
|
) |
|
|
|
type wycheproofTest struct { |
|
Algorithm string `json:"algorithm"` |
|
GeneratorVersion string `json:"generatorVersion"` |
|
NumberOfTests int `json:"numberOfTests"` |
|
Notes map[string]string `json:"notes"` |
|
Header []string `json:"header"` |
|
// encoding/json does not support collecting unused keys, so we leave |
|
// everything past this point as generic. |
|
TestGroups []map[string]interface{} `json:"testGroups"` |
|
} |
|
|
|
func sortedKeys(m map[string]interface{}) []string { |
|
keys := make([]string, 0, len(m)) |
|
for k, _ := range m { |
|
keys = append(keys, k) |
|
} |
|
sort.Strings(keys) |
|
return keys |
|
} |
|
|
|
func printAttribute(w io.Writer, key string, valueI interface{}, isInstruction bool) error { |
|
switch value := valueI.(type) { |
|
case float64: |
|
if float64(int(value)) != value { |
|
panic(key + "was not an integer.") |
|
} |
|
if isInstruction { |
|
if _, err := fmt.Fprintf(w, "[%s = %d]\n", key, int(value)); err != nil { |
|
return err |
|
} |
|
} else { |
|
if _, err := fmt.Fprintf(w, "%s = %d\n", key, int(value)); err != nil { |
|
return err |
|
} |
|
} |
|
case string: |
|
if strings.Contains(value, "\n") { |
|
panic(key + " contained a newline.") |
|
} |
|
if isInstruction { |
|
if _, err := fmt.Fprintf(w, "[%s = %s]\n", key, value); err != nil { |
|
return err |
|
} |
|
} else { |
|
if _, err := fmt.Fprintf(w, "%s = %s\n", key, value); err != nil { |
|
return err |
|
} |
|
} |
|
case map[string]interface{}: |
|
for _, k := range sortedKeys(value) { |
|
if err := printAttribute(w, key+"."+k, value[k], isInstruction); err != nil { |
|
return err |
|
} |
|
} |
|
default: |
|
panic(fmt.Sprintf("Unknown type for %q: %T", key, valueI)) |
|
} |
|
return nil |
|
} |
|
|
|
func printComment(w io.Writer, in string) error { |
|
const width = 80 - 2 |
|
lines := strings.Split(in, "\n") |
|
for _, line := range lines { |
|
for { |
|
if len(line) <= width { |
|
if _, err := fmt.Fprintf(w, "# %s\n", line); err != nil { |
|
return err |
|
} |
|
break |
|
} |
|
|
|
// Find the last space we can break at. |
|
n := strings.LastIndexByte(line[:width+1], ' ') |
|
if n < 0 { |
|
// The next word is too long. Wrap as soon as that word ends. |
|
n = strings.IndexByte(line[width+1:], ' ') |
|
if n < 0 { |
|
// This was the last word. |
|
if _, err := fmt.Fprintf(w, "# %s\n", line); err != nil { |
|
return nil |
|
} |
|
break |
|
} |
|
n += width + 1 |
|
} |
|
if _, err := fmt.Fprintf(w, "# %s\n", line[:n]); err != nil { |
|
return err |
|
} |
|
line = line[n+1:] // Ignore the space. |
|
} |
|
} |
|
return nil |
|
} |
|
|
|
func convertWycheproof(f io.Writer, jsonPath string) error { |
|
jsonData, err := ioutil.ReadFile(jsonPath) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
var w wycheproofTest |
|
if err := json.Unmarshal(jsonData, &w); err != nil { |
|
return err |
|
} |
|
|
|
if _, err := fmt.Fprintf(f, `# Imported from Wycheproof's %s. |
|
# This file is generated by convert_wycheproof.go. Do not edit by hand. |
|
# |
|
# Algorithm: %s |
|
# Generator version: %s |
|
|
|
`, jsonPath, w.Algorithm, w.GeneratorVersion); err != nil { |
|
return err |
|
} |
|
|
|
for _, group := range w.TestGroups { |
|
for _, k := range sortedKeys(group) { |
|
// Wycheproof files include keys in multiple formats. Skip PEM and |
|
// JWK formats. We process DER more easily. PEM has newlines and |
|
// JWK is a JSON object. |
|
if k == "type" || k == "tests" || strings.HasSuffix(k, "Pem") || strings.HasSuffix(k, "Jwk") || k == "jwk" { |
|
continue |
|
} |
|
if err := printAttribute(f, k, group[k], true); err != nil { |
|
return err |
|
} |
|
} |
|
fmt.Fprintf(f, "\n") |
|
tests := group["tests"].([]interface{}) |
|
for _, testI := range tests { |
|
test := testI.(map[string]interface{}) |
|
if _, err := fmt.Fprintf(f, "# tcId = %d\n", int(test["tcId"].(float64))); err != nil { |
|
return err |
|
} |
|
if comment, ok := test["comment"]; ok && len(comment.(string)) != 0 { |
|
if err := printComment(f, comment.(string)); err != nil { |
|
return err |
|
} |
|
} |
|
for _, k := range sortedKeys(test) { |
|
if k == "comment" || k == "flags" || k == "tcId" { |
|
continue |
|
} |
|
if err := printAttribute(f, k, test[k], false); err != nil { |
|
return err |
|
} |
|
} |
|
if flagsI, ok := test["flags"]; ok { |
|
var flags []string |
|
for _, flagI := range flagsI.([]interface{}) { |
|
flag := flagI.(string) |
|
flags = append(flags, flag) |
|
} |
|
if len(flags) != 0 { |
|
if err := printAttribute(f, "flags", strings.Join(flags, ","), false); err != nil { |
|
return err |
|
} |
|
} |
|
} |
|
if _, err := fmt.Fprintf(f, "\n"); err != nil { |
|
return err |
|
} |
|
} |
|
} |
|
return nil |
|
} |
|
|
|
var defaultInputs = []string{ |
|
"aes_cbc_pkcs5_test.json", |
|
"aes_cmac_test.json", |
|
"aes_gcm_siv_test.json", |
|
"aes_gcm_test.json", |
|
"chacha20_poly1305_test.json", |
|
"dsa_test.json", |
|
"ecdh_secp224r1_test.json", |
|
"ecdh_secp256r1_test.json", |
|
"ecdh_secp384r1_test.json", |
|
"ecdh_secp521r1_test.json", |
|
"ecdsa_secp224r1_sha224_test.json", |
|
"ecdsa_secp224r1_sha256_test.json", |
|
"ecdsa_secp224r1_sha512_test.json", |
|
"ecdsa_secp256r1_sha256_test.json", |
|
"ecdsa_secp256r1_sha512_test.json", |
|
"ecdsa_secp384r1_sha384_test.json", |
|
"ecdsa_secp384r1_sha512_test.json", |
|
"ecdsa_secp521r1_sha512_test.json", |
|
"eddsa_test.json", |
|
"hkdf_sha1_test.json", |
|
"hkdf_sha256_test.json", |
|
"hkdf_sha384_test.json", |
|
"hkdf_sha512_test.json", |
|
"hmac_sha1_test.json", |
|
"hmac_sha224_test.json", |
|
"hmac_sha256_test.json", |
|
"hmac_sha384_test.json", |
|
"hmac_sha512_test.json", |
|
"kw_test.json", |
|
"kwp_test.json", |
|
"primality_test.json", |
|
"rsa_oaep_2048_sha1_mgf1sha1_test.json", |
|
"rsa_oaep_2048_sha224_mgf1sha1_test.json", |
|
"rsa_oaep_2048_sha224_mgf1sha224_test.json", |
|
"rsa_oaep_2048_sha256_mgf1sha1_test.json", |
|
"rsa_oaep_2048_sha256_mgf1sha256_test.json", |
|
"rsa_oaep_2048_sha384_mgf1sha1_test.json", |
|
"rsa_oaep_2048_sha384_mgf1sha384_test.json", |
|
"rsa_oaep_2048_sha512_mgf1sha1_test.json", |
|
"rsa_oaep_2048_sha512_mgf1sha512_test.json", |
|
"rsa_oaep_3072_sha256_mgf1sha1_test.json", |
|
"rsa_oaep_3072_sha256_mgf1sha256_test.json", |
|
"rsa_oaep_3072_sha512_mgf1sha1_test.json", |
|
"rsa_oaep_3072_sha512_mgf1sha512_test.json", |
|
"rsa_oaep_4096_sha256_mgf1sha1_test.json", |
|
"rsa_oaep_4096_sha256_mgf1sha256_test.json", |
|
"rsa_oaep_4096_sha512_mgf1sha1_test.json", |
|
"rsa_oaep_4096_sha512_mgf1sha512_test.json", |
|
"rsa_oaep_misc_test.json", |
|
"rsa_pkcs1_2048_test.json", |
|
"rsa_pkcs1_3072_test.json", |
|
"rsa_pkcs1_4096_test.json", |
|
"rsa_pss_2048_sha1_mgf1_20_test.json", |
|
"rsa_pss_2048_sha256_mgf1_0_test.json", |
|
"rsa_pss_2048_sha256_mgf1_32_test.json", |
|
"rsa_pss_3072_sha256_mgf1_32_test.json", |
|
"rsa_pss_4096_sha256_mgf1_32_test.json", |
|
"rsa_pss_4096_sha512_mgf1_32_test.json", |
|
"rsa_pss_misc_test.json", |
|
"rsa_sig_gen_misc_test.json", |
|
"rsa_signature_2048_sha224_test.json", |
|
"rsa_signature_2048_sha256_test.json", |
|
"rsa_signature_2048_sha384_test.json", |
|
"rsa_signature_2048_sha512_test.json", |
|
"rsa_signature_3072_sha256_test.json", |
|
"rsa_signature_3072_sha384_test.json", |
|
"rsa_signature_3072_sha512_test.json", |
|
"rsa_signature_4096_sha384_test.json", |
|
"rsa_signature_4096_sha512_test.json", |
|
"rsa_signature_test.json", |
|
"x25519_test.json", |
|
"xchacha20_poly1305_test.json", |
|
} |
|
|
|
func main() { |
|
switch len(os.Args) { |
|
case 1: |
|
for _, jsonPath := range defaultInputs { |
|
if !strings.HasSuffix(jsonPath, ".json") { |
|
panic(jsonPath) |
|
} |
|
|
|
txtPath := jsonPath[:len(jsonPath)-len(".json")] + ".txt" |
|
out, err := os.Create(txtPath) |
|
if err != nil { |
|
fmt.Fprintf(os.Stderr, "Error opening output %s: %s\n", txtPath, err) |
|
os.Exit(1) |
|
} |
|
defer out.Close() |
|
|
|
if err := convertWycheproof(out, jsonPath); err != nil { |
|
fmt.Fprintf(os.Stderr, "Error converting %s: %s\n", jsonPath, err) |
|
os.Exit(1) |
|
} |
|
} |
|
|
|
case 2: |
|
if err := convertWycheproof(os.Stdout, os.Args[1]); err != nil { |
|
fmt.Fprintf(os.Stderr, "Error converting %s: %s\n", os.Args[1], err) |
|
os.Exit(1) |
|
} |
|
|
|
default: |
|
fmt.Fprintf(os.Stderr, "Usage: %s [input JSON]\n", os.Args[0]) |
|
os.Exit(1) |
|
} |
|
}
|
|
|