Skip to content

Commit e10a1d3

Browse files
Addressed review comments
* Comment out code in build_ffi.py instead of quoted string. * Check return value of wolfCrypt_init() * Complete algorithm type hash table * Change dicts into defaultdicts with a sensible value when key is missing. * Convert debug print to debug log messages * Add length checks to produce nicer exceptions.
1 parent 6135628 commit e10a1d3

3 files changed

Lines changed: 108 additions & 63 deletions

File tree

scripts/build_ffi.py

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,43 +1373,50 @@ def build_ffi(local_wolfssl, features):
13731373
union {
13741374
"""
13751375

1376-
"""
1377-
struct {
1378-
int type; /* enum wc_CipherType */
1379-
int enc;
1380-
union {
1381-
//wc_CryptoCb_AesAuthEnc aesgcm_enc;
1382-
//wc_CryptoCb_AesAuthDec aesgcm_dec;
1383-
//wc_CryptoCb_AesAuthEnc aesccm_enc;
1384-
//wc_CryptoCb_AesAuthDec aesccm_dec;
1385-
struct {
1386-
Aes* aes;
1387-
byte* out;
1388-
const byte* in;
1389-
word32 sz;
1390-
} aescbc;
1391-
//struct {
1392-
// Aes* aes;
1393-
// byte* out;
1394-
// const byte* in;
1395-
// word32 sz;
1396-
//} aesctr;
1397-
//struct {
1398-
// Aes* aes;
1399-
// byte* out;
1400-
// const byte* in;
1401-
// word32 sz;
1402-
//} aesecb;
1403-
//struct {
1404-
// Des3* des;
1405-
// byte* out;
1406-
// const byte* in;
1407-
// word32 sz;
1408-
//} des3;
1409-
//void* ctx;
1410-
};
1411-
} cipher;
1412-
"""
1376+
# The following block is commented out as there are issues with cffi code generation for the
1377+
# wc_CryptoInfo structure with two layers of anonymous unions.
1378+
# Uncommenting more parts of the cipher struct causes errors regarding conflicting struct sizes of
1379+
# other parts of the wc_CryptoInfo struct.
1380+
# Cffi cdef and the compiler seem to disagree.
1381+
#
1382+
# cdef += """
1383+
# struct {
1384+
# int type; /* enum wc_CipherType */
1385+
# int enc;
1386+
# union {
1387+
# //wc_CryptoCb_AesAuthEnc aesgcm_enc;
1388+
# //wc_CryptoCb_AesAuthDec aesgcm_dec;
1389+
# //wc_CryptoCb_AesAuthEnc aesccm_enc;
1390+
# //wc_CryptoCb_AesAuthDec aesccm_dec;
1391+
# struct {
1392+
# Aes* aes;
1393+
# byte* out;
1394+
# const byte* in;
1395+
# word32 sz;
1396+
# } aescbc;
1397+
# //struct {
1398+
# // Aes* aes;
1399+
# // byte* out;
1400+
# // const byte* in;
1401+
# // word32 sz;
1402+
# //} aesctr;
1403+
# //struct {
1404+
# // Aes* aes;
1405+
# // byte* out;
1406+
# // const byte* in;
1407+
# // word32 sz;
1408+
# //} aesecb;
1409+
# //struct {
1410+
# // Des3* des;
1411+
# // byte* out;
1412+
# // const byte* in;
1413+
# // word32 sz;
1414+
# //} des3;
1415+
# //void* ctx;
1416+
# };
1417+
# } cipher;
1418+
# """
1419+
14131420
cdef += """
14141421
struct {
14151422
int type; /* enum wc_HashType */

wolfcrypt/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@
4949
from wolfcrypt.cryptocb import CryptoCallback
5050
from wolfcrypt.exceptions import WolfCryptError
5151

52-
_lib.wolfCrypt_Init()
52+
ret = _lib.wolfCrypt_Init()
53+
if ret < 0:
54+
raise WolfCryptError(f"WolfCrypt_Init failed ({ret})")
5355

5456
if _lib.CRYPTO_CB_ENABLED:
5557
@_ffi.def_extern()

wolfcrypt/cryptocb.py

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,49 @@
2222

2323
from __future__ import annotations
2424

25+
import logging
26+
from collections import defaultdict
27+
from types import TracebackType
2528
from typing import Final
29+
2630
from typing_extensions import Self
2731

2832
from wolfcrypt._ffi import ffi as _ffi
2933
from wolfcrypt._ffi import lib as _lib
3034

3135
from wolfcrypt.exceptions import WolfCryptError
3236

33-
ALGO_TYPE_NAME: Final = {
34-
_lib.WC_ALGO_TYPE_HASH: "hash",
35-
_lib.WC_ALGO_TYPE_CIPHER: "cipher",
36-
_lib.WC_ALGO_TYPE_RNG: "rng",
37-
_lib.WC_ALGO_TYPE_SEED: "seed",
38-
}
39-
40-
HASH_TYPE_NAME: Final = {
41-
_lib.WC_HASH_TYPE_SHA: "SHA1",
42-
_lib.WC_HASH_TYPE_SHA256: "SHA256",
43-
_lib.WC_HASH_TYPE_SHA384: "SHA384",
44-
_lib.WC_HASH_TYPE_SHA512: "SHA512",
45-
_lib.WC_HASH_TYPE_SHA3_256: "SHA3_256",
46-
_lib.WC_HASH_TYPE_SHA3_384: "SHA3_384",
47-
_lib.WC_HASH_TYPE_SHA3_512: "SHA3_512",
48-
}
37+
ALGO_TYPE_NAME: Final = defaultdict(
38+
lambda: "unknown",
39+
{
40+
_lib.WC_ALGO_TYPE_NONE: "none",
41+
_lib.WC_ALGO_TYPE_HASH: "hash",
42+
_lib.WC_ALGO_TYPE_CIPHER: "cipher",
43+
_lib.WC_ALGO_TYPE_PK: "pk",
44+
_lib.WC_ALGO_TYPE_RNG: "rng",
45+
_lib.WC_ALGO_TYPE_SEED: "seed",
46+
_lib.WC_ALGO_TYPE_HMAC: "hmac",
47+
_lib.WC_ALGO_TYPE_CMAC: "cmac",
48+
_lib.WC_ALGO_TYPE_CERT: "cert",
49+
_lib.WC_ALGO_TYPE_KDF: "kdf",
50+
_lib.WC_ALGO_TYPE_COPY: "copy",
51+
_lib.WC_ALGO_TYPE_FREE: "free",
52+
_lib.WC_ALGO_TYPE_MAX: "max",
53+
},
54+
)
55+
56+
HASH_TYPE_NAME: Final = defaultdict(
57+
lambda: "unknown",
58+
{
59+
_lib.WC_HASH_TYPE_SHA: "SHA1",
60+
_lib.WC_HASH_TYPE_SHA256: "SHA256",
61+
_lib.WC_HASH_TYPE_SHA384: "SHA384",
62+
_lib.WC_HASH_TYPE_SHA512: "SHA512",
63+
_lib.WC_HASH_TYPE_SHA3_256: "SHA3_256",
64+
_lib.WC_HASH_TYPE_SHA3_384: "SHA3_384",
65+
_lib.WC_HASH_TYPE_SHA3_512: "SHA3_512",
66+
},
67+
)
4968

5069
DIGEST_SIZE: Final = {
5170
_lib.WC_HASH_TYPE_SHA: 20,
@@ -57,10 +76,13 @@
5776
_lib.WC_HASH_TYPE_SHA3_512: 64,
5877
}
5978

79+
log = logging.getLogger(__name__)
80+
6081

6182
if _lib.CRYPTO_CB_ENABLED:
83+
6284
class CryptoCallback:
63-
def __init__(self, device_id: int):
85+
def __init__(self, device_id: int) -> None:
6486
self.device_id = device_id
6587
self.ctx = _ffi.new_handle(self)
6688
ret = _lib.wc_CryptoCb_RegisterDevice(device_id, _lib.py_wc_crypto_callback, self.ctx)
@@ -70,30 +92,46 @@ def __init__(self, device_id: int):
7092
def __enter__(self) -> Self:
7193
return self
7294

73-
def __exit__(self, exc_type, exc_value, traceback) -> None:
95+
def __exit__(
96+
self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
97+
) -> bool:
7498
self._unregister()
99+
return False
75100

76101
def __del__(self) -> None:
77102
self._unregister()
78103

79104
def callback(self, device_id: int, info: _ffi.CData) -> int:
80-
print(f"{device_id=} algo = {ALGO_TYPE_NAME[info.algo_type]}")
81-
# _lib.wc_CryptoCb_InfoString(info)
105+
log.debug(f"{device_id=} algo = {ALGO_TYPE_NAME[info.algo_type]}")
82106
try:
83107
if info.algo_type == _lib.WC_ALGO_TYPE_HASH:
84-
print(f"hash = {HASH_TYPE_NAME[info.hash.type]}")
85-
print(f"{info.hash.data=} {info.hash.data_size=} {info.hash.digest=} {info.hash.u.sha256=}")
108+
if info.hash.type not in DIGEST_SIZE:
109+
return _lib.CRYPTOCB_UNAVAILABLE
110+
log.debug("hash = %s", HASH_TYPE_NAME[info.hash.type])
86111
if info.hash.digest == _ffi.NULL:
87-
self.hash_update_callback(device_id, info.hash.type, bytes(_ffi.buffer(info.hash.data, info.hash.data_size)))
112+
self.hash_update_callback(
113+
device_id,
114+
info.hash.type,
115+
bytes(_ffi.buffer(info.hash.data, info.hash.data_size)),
116+
)
88117
else:
89118
digest = self.hash_finalize_callback(device_id, info.hash.type)
119+
if len(digest) != DIGEST_SIZE[info.hash.type]:
120+
raise ValueError(
121+
f"Generated digest is expected to be {DIGEST_SIZE[info.hash.type]} bytes long, "
122+
f"but is {len(digest)} bytes long"
123+
)
90124
_ffi.buffer(info.hash.digest, DIGEST_SIZE[info.hash.type])[:] = digest
91125
return 0
92126
if info.algo_type == _lib.WC_ALGO_TYPE_CIPHER:
93127
self.cipher_callback(device_id)
94128
return 0
95129
if info.algo_type == _lib.WC_ALGO_TYPE_RNG:
96130
out = self.rng_callback(device_id, info.rng.rng, info.rng.sz)
131+
if len(out) != info.rng.sz:
132+
raise ValueError(
133+
f"Generated random is expected to be {info.rng.sz} bytes long, but is {len(out)} bytes long"
134+
)
97135
_ffi.buffer(info.rng.out, info.rng.sz)[:] = out
98136
return 0
99137
return _lib.CRYPTOCB_UNAVAILABLE
@@ -104,11 +142,9 @@ def rng_callback(self, device_id: int, rng, size: int) -> bytes:
104142
raise NotImplementedError
105143

106144
def hash_update_callback(self, device_id: int, hash_type: int, data: bytes) -> None:
107-
print("hash_update_callback")
108145
raise NotImplementedError
109146

110147
def hash_finalize_callback(self, device_id: int, hash_type: int) -> bytes:
111-
print("hash_finalize_callback")
112148
raise NotImplementedError
113149

114150
def cipher_callback(self, device_id: int) -> None:

0 commit comments

Comments
 (0)