Gemini proposed this to convert
```
import json
import requests
def to_c_hex(hex_str):
if not hex_str: return "NULL"
bytes_list = [f"0x{hex_str[i:i+2]}" for i in range(0, len(hex_str), 2)]
return "{" + ",".join(bytes_list) + "}"
url = "https://raw.githubusercontent.com/C2SP/wycheproof/main/testvectors_v1/aes_siv_cmac_test.json"
data = requests.get(url).json()
print("#include <stdint.h>\n#include <stddef.h>\n")
print("typedef struct { int tcId; const char* comment; uint8_t key[64]; size_t keyLen; const uint8_t* aad; size_t aadLen; const uint8_t* msg; size_t msgLen; const uint8_t* ct; size_t ctLen; const char* result; } aes_siv_test_case;\n")
for group in data['testGroups']:
for test in group['tests']:
tid = test['tcId']
if test['aad']: print(f"static const uint8_t aad_{tid}[] = {to_c_hex(test['aad'])};")
if test['msg']: print(f"static const uint8_t msg_{tid}[] = {to_c_hex(test['msg'])};")
if test['ct']: print(f"static const uint8_t ct_{tid}[] = {to_c_hex(test['ct'])};")
print("\nstatic const aes_siv_test_case aes_siv_tests[] = {")
for group in data['testGroups']:
for test in group['tests']:
tid = test['tcId']
key_hex = to_c_hex(test['key'])
aad_ptr = f"aad_{tid}" if test['aad'] else "NULL"
msg_ptr = f"msg_{tid}" if test['msg'] else "NULL"
ct_ptr = f"ct_{tid}" if test['ct'] else "NULL"
print(f" {{ {tid}, \"{test['comment']}\", {key_hex}, {len(test['key'])//2}, {aad_ptr}, {len(test['aad'])//2}, {msg_ptr}, {len(test['msg'])//2}, {ct_ptr}, {len(test['ct'])//2}, \"{test['result']}\" }},")
print("};")
```
I manually modified the result type to be an enum.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
This also changes the API, since we need to know how many ADs are passed
and can't rely on a NULL element, as an empty element also changes the
tag.
Fixes: faa8cd71e5 ("add SIV")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Since the SHA-NI checker does the same for all three versions, we only have
to make one version public. This also now enables explicit testing of the
SHA-NI blocks.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Hopefully at one point we can get rid of its duplication. Why again don't
we use inline functions as they should be used?
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
This also:
a) deprecates the old RSA and PKCS#1 API.
b) reverts the changes done to them in order to make the now deprecated API
compatible again with the last release.
The fixes commit mentioned below is the testcase for the Bleichenbacher
attack, which works now again as expected.
Fixes: 9d03c38e ("add flags to `der_decode_sequence()`")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Slightly minimize both space and time when importing a
SubjectPublicKeyInfo. Time for ECC keys stays the same.
Those tests were done with X.509 support already available, but later these
commits were split up to be independent of the X.509 feature.
Running the entire set of pem files through `x509_verify` via [0]
resp. the timing app via [1] resulted in the following data:
Before this patch:
[0]
```
==1031519== HEAP SUMMARY:
==1031519== in use at exit: 0 bytes in 0 blocks
==1031519== total heap usage: 424,057 allocs, 424,057 frees, 73,527,730 bytes allocated
```
[1]
```
x509 cert-rsa-pss.pem : 50021 cycles
x509 LTC_CA.pem : 10335 cycles
x509 LTC_S0.pem : 47284 cycles
x509 LTC_SS0.pem : 36687 cycles
x509 secp384r1.pem : 1985416 cycles
x509 secp521r1.pem : 3287773 cycles
x509 LTC_SSS0.pem : 25086 cycles
x509 secp224r1.pem : 775807 cycles
```
After this patch:
[0]
```
==1043548== HEAP SUMMARY:
==1043548== in use at exit: 0 bytes in 0 blocks
==1043548== total heap usage: 337,244 allocs, 337,244 frees, 65,047,463 bytes allocated
```
[1]
```
x509 cert-rsa-pss.pem : 32568 cycles
x509 LTC_CA.pem : 5478 cycles
x509 LTC_S0.pem : 36093 cycles
x509 LTC_SS0.pem : 23351 cycles
x509 secp384r1.pem : 1984030 cycles
x509 secp521r1.pem : 3303396 cycles
x509 LTC_SSS0.pem : 13220 cycles
x509 secp224r1.pem : 781534 cycles
```
[0] find tests/x509 -name '*.pem' -exec valgrind --leak-check=full --show-leak-kinds=all './x509_verify' {} \+
[1] ./timing x509
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
In decrypt mode (mode==1), s_ocb_done was XORing `ct[x]` into the
checksum before writing the output. The function's parameter names are
misleading (the header comment notes pt/ct really mean in/out), so in
decrypt mode `ct` is the not-yet-written *output* buffer and `pt` is
the *input* ciphertext. Reading from `ct` only worked when callers
aliased the input and output buffers (in-place decryption), as the
self-test does. Callers passing distinct buffers got CRYPT_OK with
stat=0 -- correct plaintext but failed tag verification.
Fix by reading from `pt[x]` (the input). Add a separate-buffer
regression case to ocb_test that runs against every existing test
vector and was confirmed to fail without the fix.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>