summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2018-08-26 17:38:16 +0000
committertb <>2018-08-26 17:38:16 +0000
commit4088c520e78b350eb99a6827074a3e93b4239fa4 (patch)
treee6286d314ba542dbbc0a4d4b681e34f5e9899759 /src
parent61d5fc0435582bb13dda9052c4ad758c3c1cc569 (diff)
downloadopenbsd-4088c520e78b350eb99a6827074a3e93b4239fa4.tar.gz
openbsd-4088c520e78b350eb99a6827074a3e93b4239fa4.tar.bz2
openbsd-4088c520e78b350eb99a6827074a3e93b4239fa4.zip
Run Wycheproof AES-CBC-PKCS5 testvectors against libcrypto.
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/wycheproof/wycheproof.go190
1 files changed, 189 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
index dbe4f0272e..5e2b4c9758 100644
--- a/src/regress/lib/libcrypto/wycheproof/wycheproof.go
+++ b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
@@ -1,4 +1,4 @@
1/* $OpenBSD: wycheproof.go,v 1.22 2018/08/26 17:35:40 tb Exp $ */ 1/* $OpenBSD: wycheproof.go,v 1.23 2018/08/26 17:38:16 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
@@ -56,6 +56,24 @@ import (
56 56
57const testVectorPath = "/usr/local/share/wycheproof/testvectors" 57const testVectorPath = "/usr/local/share/wycheproof/testvectors"
58 58
59type wycheproofTestGroupAesCbcPkcs5 struct {
60 IVSize int `json:"ivSize"`
61 KeySize int `json:"keySize"`
62 Type string `json:"type"`
63 Tests []*wycheproofTestAesCbcPkcs5 `json:"tests"`
64}
65
66type wycheproofTestAesCbcPkcs5 struct {
67 TCID int `json:"tcId"`
68 Comment string `json:"comment"`
69 Key string `json:"key"`
70 IV string `json:"iv"`
71 Msg string `json:"msg"`
72 CT string `json:"ct"`
73 Result string `json:"result"`
74 Flags []string `json:"flags"`
75}
76
59type wycheproofTestGroupChaCha20Poly1305 struct { 77type wycheproofTestGroupChaCha20Poly1305 struct {
60 IVSize int `json:"ivSize"` 78 IVSize int `json:"ivSize"`
61 KeySize int `json:"keySize"` 79 KeySize int `json:"keySize"`
@@ -225,6 +243,169 @@ func hashFromString(hs string) (hash.Hash, error) {
225 } 243 }
226} 244}
227 245
246func checkAesCbcPkcs5Open(ctx *C.EVP_CIPHER_CTX, key []byte, keyLen int, iv []byte, ivLen int, ct []byte, ctLen int, msg []byte, msgLen int, wt *wycheproofTestAesCbcPkcs5) bool {
247 C.EVP_CipherInit_ex(ctx, nil, nil, (*C.uchar)(unsafe.Pointer(&key[0])), (*C.uchar)(unsafe.Pointer(&iv[0])), 0)
248
249 out := make([]byte, ctLen)
250 var outlen C.int
251
252 ret := C.EVP_CipherUpdate(ctx, (*C.uchar)(unsafe.Pointer(&out[0])), &outlen, (*C.uchar)(unsafe.Pointer(&ct[0])), C.int(ctLen))
253 if ret != 1 {
254 if wt.Result == "invalid" {
255 fmt.Printf("INFO: Test case %d (%q) - EVP_CipherUpdate() = %d, want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
256 return true
257 }
258 fmt.Printf("FAIL: Test case %d (%q) - EVP_CipherUpdate() = %d, want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
259 return false
260 }
261
262 var finallen C.int
263 ret = C.EVP_CipherFinal_ex(ctx, (*C.uchar)(unsafe.Pointer(&out[outlen])), &finallen)
264 if ret != 1 {
265 if wt.Result == "invalid" {
266 return true
267 }
268 fmt.Printf("FAIL: Test case %d (%q) - EVP_CipherFinal_ex() = %d, want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
269 return false
270 }
271
272 outlen += finallen
273 if (outlen != C.int(msgLen)) {
274 fmt.Printf("FAIL: Test case %d (%q) - open length mismatch: got %d, want %d\n", wt.TCID, wt.Comment, outlen, msgLen)
275 return false
276 }
277
278 openedMsg := out[0:outlen]
279 if (msgLen == 0) {
280 msg = nil
281 }
282
283 success := false
284 if (bytes.Equal(openedMsg, msg)) || wt.Result == "invalid" {
285 success = true
286 } else {
287 fmt.Printf("FAIL: Test case %d (%q) - msg match: %t; want %v\n", wt.TCID, wt.Comment, bytes.Equal(openedMsg, msg), wt.Result)
288 }
289 return success
290}
291
292func checkAesCbcPkcs5Seal(ctx *C.EVP_CIPHER_CTX, key []byte, keyLen int, iv []byte, ivLen int, ct []byte, ctLen int, msg []byte, msgLen int, wt *wycheproofTestAesCbcPkcs5) bool {
293 C.EVP_CipherInit_ex(ctx, nil, nil, (*C.uchar)(unsafe.Pointer(&key[0])), (*C.uchar)(unsafe.Pointer(&iv[0])), 1)
294
295 out := make([]byte, msgLen + C.EVP_MAX_BLOCK_LENGTH)
296 var outlen C.int
297
298 ret := C.EVP_CipherUpdate(ctx, (*C.uchar)(unsafe.Pointer(&out[0])), &outlen, (*C.uchar)(unsafe.Pointer(&msg[0])), C.int(msgLen))
299 if ret != 1 {
300 if wt.Result == "invalid" {
301 fmt.Printf("INFO: Test case %d (%q) - EVP_CipherUpdate() = %d, want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
302 return true
303 }
304 fmt.Printf("FAIL: Test case %d (%q) - EVP_CipherUpdate() = %d, want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
305 return false
306 }
307
308 var finallen C.int
309 ret = C.EVP_CipherFinal_ex(ctx, (*C.uchar)(unsafe.Pointer(&out[outlen])), &finallen)
310 if ret != 1 {
311 if wt.Result == "invalid" {
312 return true
313 }
314 fmt.Printf("FAIL: Test case %d (%q) - EVP_CipherFinal_ex() = %d, want %v\n", wt.TCID, wt.Comment, ret, wt.Result)
315 return false
316 }
317
318 outlen += finallen
319 if (outlen != C.int(ctLen) && wt.Result != "invalid") {
320 fmt.Printf("FAIL: Test case %d (%q) - open length mismatch: got %d, want %d; result: %v\n", wt.TCID, wt.Comment, outlen, msgLen, wt.Result)
321 return false
322 }
323
324 sealedMsg := out[0:outlen]
325 if (ctLen == 0) {
326 ct = nil
327 }
328
329 success := false
330 if (bytes.Equal(sealedMsg, ct)) || wt.Result == "invalid" {
331 success = true
332 } else {
333 fmt.Printf("FAIL: Test case %d (%q) - msg match: %t; want %v\n", wt.TCID, wt.Comment, bytes.Equal(sealedMsg, ct), wt.Result)
334 }
335 return success
336}
337
338func runAesCbcPkcs5Test(ctx *C.EVP_CIPHER_CTX, wt *wycheproofTestAesCbcPkcs5) bool {
339 key, err := hex.DecodeString(wt.Key)
340 if err != nil {
341 log.Fatalf("Failed to decode key %q: %v", wt.Key, err)
342 }
343 iv, err := hex.DecodeString(wt.IV)
344 if err != nil {
345 log.Fatalf("Failed to decode IV %q: %v", wt.IV, err)
346 }
347 ct, err := hex.DecodeString(wt.CT)
348 if err != nil {
349 log.Fatalf("Failed to decode CT %q: %v", wt.CT, err)
350 }
351 msg, err := hex.DecodeString(wt.Msg)
352 if err != nil {
353 log.Fatalf("Failed to decode message %q: %v", wt.Msg, err)
354 }
355
356 keyLen, ivLen, ctLen, msgLen := len(key), len(iv), len(ct), len(msg)
357
358 if (keyLen == 0) {
359 key = append(key, 0)
360 }
361 if (ivLen == 0) {
362 iv = append(iv, 0)
363 }
364 if (ctLen == 0) {
365 ct = append(ct, 0)
366 }
367 if (msgLen == 0) {
368 msg = append(msg, 0)
369 }
370
371 openSuccess := checkAesCbcPkcs5Open(ctx, key, keyLen, iv, ivLen, ct, ctLen, msg, msgLen, wt)
372 sealSuccess := checkAesCbcPkcs5Seal(ctx, key, keyLen, iv, ivLen, ct, ctLen, msg, msgLen, wt)
373
374 return openSuccess && sealSuccess
375}
376
377func runAesCbcPkcs5TestGroup(wtg *wycheproofTestGroupAesCbcPkcs5) bool {
378 fmt.Printf("Running AES-CBC-PKCS5 test group %v with IV size %d and key size %d\n", wtg.Type, wtg.IVSize, wtg.KeySize)
379
380 var cipher *C.EVP_CIPHER
381 switch wtg.KeySize {
382 case 128:
383 cipher = C.EVP_aes_128_cbc()
384 case 192:
385 cipher = C.EVP_aes_192_cbc()
386 case 256:
387 cipher = C.EVP_aes_256_cbc()
388 default:
389 log.Fatalf("Unsupported key size: %d", wtg.KeySize)
390 }
391
392 ctx := C.EVP_CIPHER_CTX_new()
393 if ctx == nil {
394 log.Fatal("EVP_CIPHER_CTX_new() failed")
395 }
396 defer C.EVP_CIPHER_CTX_free(ctx)
397
398 C.EVP_CipherInit_ex(ctx, cipher, nil, nil, nil, 0)
399
400 success := true
401 for _, wt := range wtg.Tests {
402 if !runAesCbcPkcs5Test(ctx, wt) {
403 success = false
404 }
405 }
406 return success
407}
408
228func checkChaCha20Poly1305Open(ctx *C.EVP_AEAD_CTX, iv []byte, ivLen int, aad []byte, aadLen int, msg []byte, msgLen int, ct []byte, ctLen int, tag []byte, tagLen int, wt *wycheproofTestChaCha20Poly1305) bool { 409func checkChaCha20Poly1305Open(ctx *C.EVP_AEAD_CTX, iv []byte, ivLen int, aad []byte, aadLen int, msg []byte, msgLen int, ct []byte, ctLen int, tag []byte, tagLen int, wt *wycheproofTestChaCha20Poly1305) bool {
229 maxOutLen := ctLen + tagLen 410 maxOutLen := ctLen + tagLen
230 411
@@ -728,6 +909,8 @@ func runTestVectors(path string) bool {
728 909
729 var wtg interface{} 910 var wtg interface{}
730 switch wtv.Algorithm { 911 switch wtv.Algorithm {
912 case "AES-CBC-PKCS5":
913 wtg = &wycheproofTestGroupAesCbcPkcs5{}
731 case "CHACHA20-POLY1305": 914 case "CHACHA20-POLY1305":
732 wtg = &wycheproofTestGroupChaCha20Poly1305{} 915 wtg = &wycheproofTestGroupChaCha20Poly1305{}
733 case "DSA": 916 case "DSA":
@@ -748,6 +931,10 @@ func runTestVectors(path string) bool {
748 log.Fatalf("Failed to unmarshal test groups JSON: %v", err) 931 log.Fatalf("Failed to unmarshal test groups JSON: %v", err)
749 } 932 }
750 switch wtv.Algorithm { 933 switch wtv.Algorithm {
934 case "AES-CBC-PKCS5":
935 if !runAesCbcPkcs5TestGroup(wtg.(*wycheproofTestGroupAesCbcPkcs5)) {
936 success = false
937 }
751 case "CHACHA20-POLY1305": 938 case "CHACHA20-POLY1305":
752 if !runChaCha20Poly1305TestGroup(wtg.(*wycheproofTestGroupChaCha20Poly1305)) { 939 if !runChaCha20Poly1305TestGroup(wtg.(*wycheproofTestGroupChaCha20Poly1305)) {
753 success = false 940 success = false
@@ -787,6 +974,7 @@ func main() {
787 name string 974 name string
788 pattern string 975 pattern string
789 }{ 976 }{
977 {"AES", "aes_cbc*test.json"},
790 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"}, 978 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"},
791 {"DSA", "dsa_test.json"}, 979 {"DSA", "dsa_test.json"},
792 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now. 980 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now.