Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions tests/test_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ def test_byte(rng):


def test_bytes(rng):
assert len(rng.bytes(1)) == 1
assert len(rng.bytes(8)) == 8
assert len(rng.bytes(128)) == 128
assert len(rng.randbytes(1)) == 1
assert len(rng.randbytes(8)) == 8
assert len(rng.randbytes(128)) == 128

@pytest.fixture
def rng_nonce():
Expand All @@ -47,4 +47,4 @@ def test_nonce_byte(rng_nonce):

@pytest.mark.parametrize("length", (1, 8, 128))
def test_nonce_bytes(rng_nonce, length):
assert len(rng_nonce.bytes(length)) == length
assert len(rng_nonce.randbytes(length)) == length
5 changes: 5 additions & 0 deletions wolfcrypt/_ffi/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import _cffi_backend

ffi: _cffi_backend.FFI

__all__ = ["lib"]
90 changes: 90 additions & 0 deletions wolfcrypt/_ffi/lib.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@

from _cffi_backend import FFI
from typing_extensions import TypeAlias

INVALID_DEVID: int

AES_ENABLED: int
AES_SIV_ENABLED: int
AESGCM_STREAM_ENABLED: int
ASN_ENABLED: int
CHACHA_ENABLED: int
CHACHA_STREAM_ENABLED: int
CHACHA20_POLY1305_ENABLED: int
DES3_ENABLED: int
ECC_ENABLED: int
ED25519_ENABLED: int
ED448_ENABLED: int
FIPS_ENABLED: int
HMAC_ENABLED: int
KEYGEN_ENABLED: int
HKDF_ENABLED: int
ML_DSA_ENABLED: int
ML_KEM_ENABLED: int
MPAPI_ENABLED: int
PWDBASED_ENABLED: int
RSA_ENABLED: int
RSA_PSS_ENABLED: int
SHA_ENABLED: int
SHA3_ENABLED: int
SHA256_ENABLED: int
SHA384_ENABLED: int
SHA512_ENABLED: int
WC_RNG_SEED_CB_ENABLED: int

FIPS_VERSION: int

WC_MGF1NONE: int
WC_MGF1SHA1: int
WC_MGF1SHA224: int
WC_MGF1SHA256: int
WC_MGF1SHA384: int
WC_MGF1SHA512: int

WC_HASH_TYPE_NONE: int
WC_HASH_TYPE_MD2: int
WC_HASH_TYPE_MD4: int
WC_HASH_TYPE_MD5: int
WC_HASH_TYPE_SHA: int
WC_HASH_TYPE_SHA224: int
WC_HASH_TYPE_SHA256: int
WC_HASH_TYPE_SHA384: int
WC_HASH_TYPE_SHA512: int
WC_HASH_TYPE_MD5_SHA: int
WC_HASH_TYPE_SHA3_224: int
WC_HASH_TYPE_SHA3_256: int
WC_HASH_TYPE_SHA3_384: int
WC_HASH_TYPE_SHA3_512: int
WC_HASH_TYPE_BLAKE2B: int
WC_HASH_TYPE_BLAKE2S: int

WC_ML_KEM_512: int
WC_ML_KEM_768: int
WC_ML_KEM_1024: int

WC_ML_DSA_44: int
WC_ML_DSA_65: int
WC_ML_DSA_87: int

WC_KEYTYPE_ALL: int

RNG: TypeAlias = FFI.CData

def wc_InitRngNonce_ex(rng: RNG, nonce: FFI.CData, nonce_size: int, heap: FFI.CData, device_id: int) -> int: ...
def wc_RNG_GenerateByte(rng: RNG, buffer: FFI.CData) -> int: ...
def wc_RNG_GenerateBlock(rng: RNG, buffer: FFI.CData, len: int) -> int: ...
def wc_FreeRng(rng: RNG) -> None: ...
def wc_SetSeed_Cb(cdata: FFI.CData) -> int: ...

def wc_FreeRsaKey() -> None: ...

def wc_ecc_free() -> None: ...

def wc_ed25519_free() -> None: ...

def wc_ed448_free() -> None: ...

def wc_KyberKey_DecodePrivateKey() -> int: ...
def wc_KyberKey_Decapsulate() -> int: ...

def wolfCrypt_SetPrivateKeyReadEnable_fips(a: int, b: int) -> int: ...
6 changes: 2 additions & 4 deletions wolfcrypt/ciphers.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,6 @@ class ChaCha(_Cipher):
key_size = None # 16, 24, 32
_key_sizes = [16, 32]
_native_type = "ChaCha *"
_IV_nonce = []
_IV_counter = 0

def __init__(self, key="", size=32):
self._native_object = _ffi.new(self._native_type)
Expand All @@ -501,7 +499,7 @@ def __init__(self, key="", size=32):
raise ValueError("Invalid key size %d" % size)
self._key = t2b(key)
self.key_size = size
self._IV_nonce = []
self._IV_nonce = b""
self._IV_counter = 0

def _set_key(self, direction):
Expand Down Expand Up @@ -1990,7 +1988,7 @@ def encode_priv_key(self):

return _ffi.buffer(priv_key, priv_key_size)[:]

def decode_key(self, priv_key: tuple[bytes, str]):
def decode_key(self, priv_key: bytes):
"""
:param priv_key: private key to be imported
:type priv_key: bytes or str
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/hashes.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class _Hmac(_Hash):
A **PEP 247: Cryptographic Hash Functions** compliant
**Keyed Hash Function Interface**.
"""
digest_size = None
digest_size = 0
_native_type = "Hmac *"
_native_size = _ffi.sizeof("Hmac")

Expand Down
18 changes: 12 additions & 6 deletions wolfcrypt/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

# pylint: disable=no-member,no-name-in-module

from __future__ import annotations

from _cffi_backend import FFI

from wolfcrypt._ffi import ffi as _ffi
from wolfcrypt._ffi import lib as _lib

Expand All @@ -31,8 +35,8 @@ class Random(object):
A Cryptographically Secure Pseudo Random Number Generator - CSPRNG
"""

def __init__(self, nonce=_ffi.NULL, device_id=_lib.INVALID_DEVID):
self.native_object = _ffi.new("WC_RNG *")
def __init__(self, nonce=_ffi.NULL, device_id=_lib.INVALID_DEVID) -> None:
self.native_object: FFI.CData | None = _ffi.new("WC_RNG *")

if nonce == _ffi.NULL:
nonce_size = 0
Expand All @@ -46,32 +50,34 @@ def __init__(self, nonce=_ffi.NULL, device_id=_lib.INVALID_DEVID):
# making sure _lib.wc_FreeRng outlives WC_RNG instances
_delete = _lib.wc_FreeRng

def __del__(self):
def __del__(self) -> None:
if self.native_object:
try:
self._delete(self.native_object)
Random._delete(self.native_object)
except AttributeError:
# Can occur during interpreter shutdown
pass

def byte(self):
def byte(self) -> bytes:
"""
Generate and return a random byte.
"""
result = _ffi.new('byte[1]')

assert self.native_object is not None
ret = _lib.wc_RNG_GenerateByte(self.native_object, result)
if ret < 0: # pragma: no cover
raise WolfCryptError("RNG generate byte error (%d)" % ret)

return _ffi.buffer(result, 1)[:]

def bytes(self, length):
def randbytes(self, length) -> bytes:
"""
Generate and return a random sequence of length bytes.
"""
result = _ffi.new('byte[%d]' % length)

assert self.native_object is not None
ret = _lib.wc_RNG_GenerateBlock(self.native_object, result, length)
if ret < 0: # pragma: no cover
raise WolfCryptError("RNG generate block error (%d)" % ret)
Expand Down
6 changes: 4 additions & 2 deletions wolfcrypt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@

# pylint: disable=unused-import

from __future__ import annotations

from binascii import hexlify as b2h, unhexlify as h2b # noqa: F401


def t2b(string):
def t2b(string: bytes | bytearray | memoryview | str) -> bytes:
"""
Converts text to binary.

Passes through bytes, bytearray, and memoryview unchanged.
Encodes str to UTF-8 bytes.
"""
if isinstance(string, (bytes, bytearray, memoryview)):
return string
return bytes(string)
return str(string).encode("utf-8")
Loading