Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/poly1305.py: 32%

34 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:36 +0000

1# This file is dual licensed under the terms of the Apache License, Version 

2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 

3# for complete details. 

4 

5import typing 

6 

7from cryptography.exceptions import InvalidSignature 

8from cryptography.hazmat.primitives import constant_time 

9 

10_POLY1305_TAG_SIZE = 16 

11_POLY1305_KEY_SIZE = 32 

12 

13 

14if typing.TYPE_CHECKING: 

15 from cryptography.hazmat.backends.openssl.backend import Backend 

16 

17 

18class _Poly1305Context: 

19 def __init__(self, backend: "Backend", key: bytes) -> None: 

20 self._backend = backend 

21 

22 key_ptr = self._backend._ffi.from_buffer(key) 

23 # This function copies the key into OpenSSL-owned memory so we don't 

24 # need to retain it ourselves 

25 evp_pkey = self._backend._lib.EVP_PKEY_new_raw_private_key( 

26 self._backend._lib.NID_poly1305, 

27 self._backend._ffi.NULL, 

28 key_ptr, 

29 len(key), 

30 ) 

31 self._backend.openssl_assert(evp_pkey != self._backend._ffi.NULL) 

32 self._evp_pkey = self._backend._ffi.gc( 

33 evp_pkey, self._backend._lib.EVP_PKEY_free 

34 ) 

35 ctx = self._backend._lib.EVP_MD_CTX_new() 

36 self._backend.openssl_assert(ctx != self._backend._ffi.NULL) 

37 self._ctx = self._backend._ffi.gc( 

38 ctx, self._backend._lib.EVP_MD_CTX_free 

39 ) 

40 res = self._backend._lib.EVP_DigestSignInit( 

41 self._ctx, 

42 self._backend._ffi.NULL, 

43 self._backend._ffi.NULL, 

44 self._backend._ffi.NULL, 

45 self._evp_pkey, 

46 ) 

47 self._backend.openssl_assert(res == 1) 

48 

49 def update(self, data: bytes) -> None: 

50 data_ptr = self._backend._ffi.from_buffer(data) 

51 res = self._backend._lib.EVP_DigestSignUpdate( 

52 self._ctx, data_ptr, len(data) 

53 ) 

54 self._backend.openssl_assert(res != 0) 

55 

56 def finalize(self) -> bytes: 

57 buf = self._backend._ffi.new("unsigned char[]", _POLY1305_TAG_SIZE) 

58 outlen = self._backend._ffi.new("size_t *", _POLY1305_TAG_SIZE) 

59 res = self._backend._lib.EVP_DigestSignFinal(self._ctx, buf, outlen) 

60 self._backend.openssl_assert(res != 0) 

61 self._backend.openssl_assert(outlen[0] == _POLY1305_TAG_SIZE) 

62 return self._backend._ffi.buffer(buf)[: outlen[0]] 

63 

64 def verify(self, tag: bytes) -> None: 

65 mac = self.finalize() 

66 if not constant_time.bytes_eq(mac, tag): 

67 raise InvalidSignature("Value did not match computed tag.")