mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-02-04 15:39:53 +00:00
Reject invalid MAC and AEAD truncations
Reject algorithms of the form PSA_ALG_TRUNCATED_MAC(...) or PSA_ALG_AEAD_WITH_SHORTENED_TAG(...) when the truncation length is invalid or not accepted by policy in Mbed TLS. This is done in KeyType.can_do, so in generate_psa_tests.py, keys will be tested for operation failure with this algorithm if the algorithm is rejected, and for storage if the algorithm is accepted. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
parent
2fa829c7dd
commit
e3a0890e4f
@ -20,7 +20,7 @@ This module is entirely based on the PSA API.
|
||||
|
||||
import enum
|
||||
import re
|
||||
from typing import Iterable, List, Optional, Tuple
|
||||
from typing import FrozenSet, Iterable, List, Optional, Tuple
|
||||
|
||||
from mbedtls_dev.asymmetric_key_data import ASYMMETRIC_KEY_DATA
|
||||
|
||||
@ -216,6 +216,8 @@ class KeyType:
|
||||
#pylint: disable=too-many-return-statements
|
||||
if alg.is_wildcard:
|
||||
return False
|
||||
if alg.is_invalid_truncation():
|
||||
return False
|
||||
if self.head == 'HMAC' and alg.head == 'HMAC':
|
||||
return True
|
||||
if self.head == 'DES':
|
||||
@ -420,8 +422,55 @@ class Algorithm:
|
||||
"""
|
||||
return short_expression(self.expression, level=level)
|
||||
|
||||
PERMITTED_TAG_LENGTHS = {
|
||||
'PSA_ALG_CCM': frozenset([4, 6, 8, 10, 12, 14, 16]),
|
||||
'PSA_ALG_CHACHA20_POLY1305': frozenset([16]),
|
||||
'PSA_ALG_GCM': frozenset([4, 8, 12, 13, 14, 15, 16]),
|
||||
}
|
||||
MAC_LENGTH = {
|
||||
'PSA_ALG_CBC_MAC': 16,
|
||||
'PSA_ALG_CMAC': 16,
|
||||
'PSA_ALG_HMAC(PSA_ALG_MD5)': 16,
|
||||
'PSA_ALG_HMAC(PSA_ALG_SHA_1)': 20,
|
||||
}
|
||||
HMAC_WITH_NOMINAL_LENGTH_RE = re.compile(r'PSA_ALG_HMAC\(\w+([0-9])+\)\Z')
|
||||
@classmethod
|
||||
def mac_or_tag_length(cls, base: str) -> FrozenSet[int]:
|
||||
"""Return the set of permitted lengths for the given MAC or AEAD tag."""
|
||||
if base in cls.PERMITTED_TAG_LENGTHS:
|
||||
return cls.PERMITTED_TAG_LENGTHS[base]
|
||||
max_length = cls.MAC_LENGTH.get(base, None)
|
||||
if max_length is None:
|
||||
m = cls.HMAC_WITH_NOMINAL_LENGTH_RE.match(base)
|
||||
if m:
|
||||
max_length = int(m.group(1)) // 8
|
||||
if max_length is None:
|
||||
raise ValueError('Unknown permitted lengths for ' + base)
|
||||
return frozenset(range(4, max_length + 1))
|
||||
|
||||
TRUNCATED_ALG_RE = re.compile(
|
||||
r'(?P<face>PSA_ALG_(?:AEAD_WITH_SHORTENED_TAG|TRUNCATED_MAC))'
|
||||
r'\((?P<base>.*),'
|
||||
r'(?P<length>0[Xx][0-9A-Fa-f]+|[1-9][0-9]*|0[0-9]*)[LUlu]*\)\Z')
|
||||
def is_invalid_truncation(self) -> bool:
|
||||
"""False for a MAC or AEAD algorithm truncated to an invalid length.
|
||||
|
||||
True for a MAC or AEAD algorithm truncated to a valid length or to
|
||||
a length that cannot be determined. True for anything other than
|
||||
a truncated MAC or AEAD.
|
||||
"""
|
||||
m = self.TRUNCATED_ALG_RE.match(self.expression)
|
||||
if m:
|
||||
base = m.group('base')
|
||||
to_length = int(m.group('length'), 0)
|
||||
permitted_lengths = self.mac_or_tag_length(base)
|
||||
if to_length not in permitted_lengths:
|
||||
return True
|
||||
return False
|
||||
|
||||
def can_do(self, category: AlgorithmCategory) -> bool:
|
||||
"""Whether this algorithm fits the specified operation category."""
|
||||
"""Whether this algorithm can perform operations in the given category.
|
||||
"""
|
||||
if category == self.category:
|
||||
return True
|
||||
if category == AlgorithmCategory.KEY_DERIVATION and \
|
||||
|
Loading…
x
Reference in New Issue
Block a user