summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2024-05-22 14:03:24 +0000
committertb <>2024-05-22 14:03:24 +0000
commit3e142bb6f4125f567c0eb4cf50bbbd84ecae8a7f (patch)
tree2befa060a91c7d26156a42b60aa88b39721d1961 /src
parentc9e7f6cc4791caccd0623fc02585e3e9b39d6965 (diff)
downloadopenbsd-3e142bb6f4125f567c0eb4cf50bbbd84ecae8a7f.tar.gz
openbsd-3e142bb6f4125f567c0eb4cf50bbbd84ecae8a7f.tar.bz2
openbsd-3e142bb6f4125f567c0eb4cf50bbbd84ecae8a7f.zip
Exercise EVP_chacha20_poly1305() with in-place decryption
This needs quite a bit of cleanup but let's have some tests rather than none.
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/wycheproof/wycheproof.go145
1 files changed, 143 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
index b158c142aa..ddd37030d4 100644
--- a/src/regress/lib/libcrypto/wycheproof/wycheproof.go
+++ b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
@@ -1,7 +1,7 @@
1/* $OpenBSD: wycheproof.go,v 1.159 2023/11/07 21:22:34 tb Exp $ */ 1/* $OpenBSD: wycheproof.go,v 1.160 2024/05/22 14:03:24 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2018,2023 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018,2023 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2018,2019,2022,2023 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2018,2019,2022-2024 Theo Buehler <tb@openbsd.org>
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -1215,6 +1215,138 @@ func runChaCha20Poly1305Test(algorithm string, wt *wycheproofTestAead) bool {
1215 return openSuccess && sealSuccess 1215 return openSuccess && sealSuccess
1216} 1216}
1217 1217
1218func runEvpChaCha20Poly1305Test(ctx *C.EVP_CIPHER_CTX, algorithm string, wt *wycheproofTestAead) bool {
1219 var aead *C.EVP_CIPHER
1220 switch algorithm {
1221 case "CHACHA20-POLY1305":
1222 aead = C.EVP_chacha20_poly1305()
1223 case "XCHACHA20-POLY1305":
1224 return true
1225 }
1226
1227 key, _ := mustDecodeHexString(wt.Key, "key")
1228 iv, ivLen := mustDecodeHexString(wt.IV, "iv")
1229 aad, aadLen := mustDecodeHexString(wt.AAD, "aad")
1230 msg, msgLen := mustDecodeHexString(wt.Msg, "msg")
1231
1232 ct, err := hex.DecodeString(wt.CT)
1233 if err != nil {
1234 log.Fatalf("Failed to decode ct %q: %v", wt.CT, err)
1235 }
1236 tag, err := hex.DecodeString(wt.Tag)
1237 if err != nil {
1238 log.Fatalf("Failed to decode tag %q: %v", wt.Tag, err)
1239 }
1240 ctLen, tagLen := len(ct), len(tag)
1241
1242 if C.EVP_EncryptInit_ex(ctx, aead, nil, nil, nil) != 1 {
1243 log.Fatal("Failed to initialize EVP_CIPHER_CTX with cipher")
1244 }
1245 if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_AEAD_SET_IVLEN, C.int(ivLen), nil) != 1 {
1246 log.Fatal("Failed EVP_CTRL_AEAD_SET_IVLEN")
1247 }
1248 if C.EVP_EncryptInit_ex(ctx, nil, nil, (*C.uchar)(unsafe.Pointer(&key[0])), nil) != 1 {
1249 log.Fatal("Failed EVP_EncryptInit_ex key")
1250 }
1251 if C.EVP_EncryptInit_ex(ctx, nil, nil, nil, (*C.uchar)(unsafe.Pointer(&iv[0]))) != 1 {
1252 log.Fatal("Failed EVP_EncryptInit_ex iv")
1253 }
1254
1255 var len C.int
1256
1257 if C.EVP_EncryptUpdate(ctx, nil, (*C.int)(unsafe.Pointer(&len)), (*C.uchar)(&aad[0]), (C.int)(aadLen)) != 1 {
1258 log.Fatal("Failed EVP_EncryptUpdate aad")
1259 }
1260
1261 sealed := make([]byte, ctLen + tagLen)
1262 copy(sealed, msg)
1263 if C.EVP_EncryptUpdate(ctx, (*C.uchar)(unsafe.Pointer(&sealed[0])), (*C.int)(unsafe.Pointer(&len)), (*C.uchar)(unsafe.Pointer(&sealed[0])), (C.int)(msgLen)) != 1 {
1264 log.Fatal("Failed EVP_EncryptUpdate msg")
1265 }
1266 outLen := len
1267 if C.EVP_EncryptFinal_ex(ctx, (*C.uchar)(unsafe.Pointer(&sealed[outLen])), (*C.int)(unsafe.Pointer(&len))) != 1 {
1268 log.Fatal("Failed EVP_EncryptFinal msg")
1269 }
1270 outLen += len
1271 if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_AEAD_GET_TAG, (C.int)(tagLen), unsafe.Pointer(&sealed[outLen])) != 1 {
1272 log.Fatal("Failed EVP_CTRL_AEAD_GET_TAG")
1273 }
1274 outLen += (C.int)(tagLen)
1275
1276 if (C.int)(ctLen + tagLen) != outLen {
1277 fmt.Printf("%s\n", wt)
1278 }
1279
1280 sealSuccess := false
1281 ctMatch := bytes.Equal(ct, sealed[:ctLen])
1282 tagMatch := bytes.Equal(tag, sealed[ctLen:])
1283 if (ctMatch && tagMatch) == (wt.Result != "invalid") {
1284 sealSuccess = true
1285 } else {
1286 fmt.Printf("%s - ct match: %t tag match: %t\n", wt, ctMatch, tagMatch)
1287 }
1288
1289 if C.EVP_DecryptInit_ex(ctx, aead, nil, nil, nil) != 1 {
1290 log.Fatal("Failed to initialize EVP_CIPHER_CTX with cipher")
1291 }
1292 if C.EVP_DecryptInit_ex(ctx, nil, nil, (*C.uchar)(unsafe.Pointer(&key[0])), nil) != 1 {
1293 log.Fatal("Failed EVP_EncryptInit_ex key")
1294 }
1295
1296 if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_AEAD_SET_IVLEN, C.int(ivLen), nil) != 1 {
1297 log.Fatal("Failed EVP_CTRL_AEAD_SET_IVLEN")
1298 }
1299 if C.EVP_DecryptInit_ex(ctx, nil, nil, nil, (*C.uchar)(unsafe.Pointer(&iv[0]))) != 1 {
1300 log.Fatal("Failed EVP_EncryptInit_ex iv")
1301 }
1302
1303 if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_AEAD_SET_TAG, (C.int)(tagLen), unsafe.Pointer(&tag[0])) != 1 {
1304 log.Fatal("Failed EVP_CTRL_AEAD_SET_TAG")
1305 }
1306
1307 if ctLen == 0 {
1308 ct = append(ct, 0)
1309 }
1310
1311 opened := make([]byte, msgLen + tagLen)
1312 copy(opened, ct)
1313 if msgLen + aadLen == 0 {
1314 opened = append(opened, 0)
1315 }
1316
1317 if C.EVP_DecryptUpdate(ctx, nil, (*C.int)(unsafe.Pointer(&len)), (*C.uchar)(unsafe.Pointer(&aad[0])), C.int(aadLen)) != 1 {
1318 log.Fatal("Failed EVP_EncryptUpdate msg")
1319 }
1320
1321 if C.EVP_DecryptUpdate(ctx, (*C.uchar)(unsafe.Pointer(&opened[0])), (*C.int)(unsafe.Pointer(&len)), (*C.uchar)(unsafe.Pointer(&opened[0])), (C.int)(ctLen)) != 1 {
1322 log.Fatal("Failed EVP_EncryptUpdate msg")
1323 }
1324 outLen = len
1325
1326 var ret C.int
1327 if wt.Result != "invalid" {
1328 ret = 1
1329 }
1330
1331 if C.EVP_DecryptFinal_ex(ctx, (*C.uchar)(unsafe.Pointer(&opened[outLen])), (*C.int)(unsafe.Pointer(&len))) != ret {
1332 log.Fatalf("Failed EVP_EncryptFinal msg %s\n", wt)
1333 }
1334 outLen += len
1335
1336 openSuccess := true
1337 if (C.int)(msgLen) != outLen {
1338 openSuccess = false
1339 fmt.Printf("%s\n", wt)
1340 }
1341
1342 if wt.Result != "invalid" && !bytes.Equal(opened[:outLen], msg[:msgLen]) {
1343 fmt.Printf("failed %s\n", wt)
1344 openSuccess = false
1345 }
1346
1347 return sealSuccess && openSuccess
1348}
1349
1218func (wtg *wycheproofTestGroupChaCha) run(algorithm string, variant testVariant) bool { 1350func (wtg *wycheproofTestGroupChaCha) run(algorithm string, variant testVariant) bool {
1219 // ChaCha20-Poly1305 currently only supports nonces of length 12 (96 bits) 1351 // ChaCha20-Poly1305 currently only supports nonces of length 12 (96 bits)
1220 if algorithm == "CHACHA20-POLY1305" && wtg.IVSize != 96 { 1352 if algorithm == "CHACHA20-POLY1305" && wtg.IVSize != 96 {
@@ -1223,11 +1355,20 @@ func (wtg *wycheproofTestGroupChaCha) run(algorithm string, variant testVariant)
1223 1355
1224 fmt.Printf("Running %v test group %v with IV size %d, key size %d, tag size %d...\n", algorithm, wtg.Type, wtg.IVSize, wtg.KeySize, wtg.TagSize) 1356 fmt.Printf("Running %v test group %v with IV size %d, key size %d, tag size %d...\n", algorithm, wtg.Type, wtg.IVSize, wtg.KeySize, wtg.TagSize)
1225 1357
1358 ctx := C.EVP_CIPHER_CTX_new()
1359 if ctx == nil {
1360 log.Fatal("EVP_CIPHER_CTX_new() failed")
1361 }
1362 defer C.EVP_CIPHER_CTX_free(ctx)
1363
1226 success := true 1364 success := true
1227 for _, wt := range wtg.Tests { 1365 for _, wt := range wtg.Tests {
1228 if !runChaCha20Poly1305Test(algorithm, wt) { 1366 if !runChaCha20Poly1305Test(algorithm, wt) {
1229 success = false 1367 success = false
1230 } 1368 }
1369 if !runEvpChaCha20Poly1305Test(ctx, algorithm, wt) {
1370 success = false
1371 }
1231 } 1372 }
1232 return success 1373 return success
1233} 1374}