2222
2323from __future__ import annotations
2424
25+ import logging
26+ from collections import defaultdict
27+ from types import TracebackType
2528from typing import Final
29+
2630from typing_extensions import Self
2731
2832from wolfcrypt ._ffi import ffi as _ffi
2933from wolfcrypt ._ffi import lib as _lib
3034
3135from 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
5069DIGEST_SIZE : Final = {
5170 _lib .WC_HASH_TYPE_SHA : 20 ,
5776 _lib .WC_HASH_TYPE_SHA3_512 : 64 ,
5877}
5978
79+ log = logging .getLogger (__name__ )
80+
6081
6182if _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