diff options
author | tb <> | 2024-05-22 14:03:24 +0000 |
---|---|---|
committer | tb <> | 2024-05-22 14:03:24 +0000 |
commit | 3e142bb6f4125f567c0eb4cf50bbbd84ecae8a7f (patch) | |
tree | 2befa060a91c7d26156a42b60aa88b39721d1961 /src | |
parent | c9e7f6cc4791caccd0623fc02585e3e9b39d6965 (diff) | |
download | openbsd-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.go | 145 |
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 | ||
1218 | func 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 | |||
1218 | func (wtg *wycheproofTestGroupChaCha) run(algorithm string, variant testVariant) bool { | 1350 | func (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 | } |