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.0.1, created at 2022-12-25 06:11 +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 

11_POLY1305_TAG_SIZE = 16 

12_POLY1305_KEY_SIZE = 32 

13 

14 

15if typing.TYPE_CHECKING: 

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

17 

18 

19class _Poly1305Context: 

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

21 self._backend = backend 

22 

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

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

25 # need to retain it ourselves 

26 evp_pkey = self._backend._lib.EVP_PKEY_new_raw_private_key( 

27 self._backend._lib.NID_poly1305, 

28 self._backend._ffi.NULL, 

29 key_ptr, 

30 len(key), 

31 ) 

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

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

34 evp_pkey, self._backend._lib.EVP_PKEY_free 

35 ) 

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

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

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

39 ctx, self._backend._lib.EVP_MD_CTX_free 

40 ) 

41 res = self._backend._lib.EVP_DigestSignInit( 

42 self._ctx, 

43 self._backend._ffi.NULL, 

44 self._backend._ffi.NULL, 

45 self._backend._ffi.NULL, 

46 self._evp_pkey, 

47 ) 

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

49 

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

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

52 res = self._backend._lib.EVP_DigestSignUpdate( 

53 self._ctx, data_ptr, len(data) 

54 ) 

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

56 

57 def finalize(self) -> bytes: 

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

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

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

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

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

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

64 

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

66 mac = self.finalize() 

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

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