Template Function desfire::find_crc_tail(ByteIterator, ByteIterator, Fn&&, N, std::size_t, bool, BytesContainer const&)

Function Documentation

template<class ByteIterator, class N, class Fn, class BytesContainer>
std::pair<ByteIterator, bool> desfire::find_crc_tail(ByteIterator begin, ByteIterator end, Fn &&crc_fn, N init, std::size_t block_size, bool incremental_crc, BytesContainer const &valid_padding_bytes)

Finds the last point in a sequence where the CRC checks out and only valid_padding_bytes follow. This method is used to identify the location of a CRC code in a sequence of the type [message] [crc] [padding]. More specifically, this finds the last point in the sequence where a CRC is valid on the previous message and only padding bytes follow (at most @p block_size - 1 padding bytes). This reverses the operation of appending a CRC and then padding to a multiple of block size.

Note

In general, for a CRC function, it should hold ‘’CRC(A || B, init) = CRC(B, CRC(A, init))’’. If this is the case, specify incremental_crc true. If this is not the case (e.g. you are simulating the injection of extra data in between the data payload and the CRC), specify false. The behavior is pseudo code is as follows:

crc_i := crc_fn(data[0:i], init)
if incremental_crc:
    crc_{i+1} := crc_fn(data[i+1], crc_i)
else:
    crc_{i+1} := crc_fn(data[0:i+1], init)

Template Parameters:
  • ByteIterator – A bidirectional iterator with std::uint8_t as value type, which supports reversing, i.e. not a generator.

  • N – A unsigned integer size matching the crc size, e.g. ‘’std::uint32_t’’ for a CRC32.

  • Fn – Must match signature ‘’N crc_fn(ByteIterator b, ByteIterator e, N init)’’.

  • BytesContainer – Any byte container, possibly small and fast, since every element will be checked.

Parameters:
  • begin – Iterator to the beginning of the byte sequence.

  • end – Iterator past-the-end of the byte sequence.

  • crc_fn – Function that computes the CRC of a subsequence of bytes, starting with a given initial CRC value. This could be called to compute the CRC incrementally on adjacent subsequences, if incremental_crc is true.

  • init – Initial value for the CRC.

  • block_size – Padding block size: this represent how long at most a sequence of padding bytes can be, and corresponds to the maximum number of bytes we need to check for a valid CRC. In other words, the [message] [crc] sequence, must have been padded to the next multiple of block_size.

  • incremental_crc – If true, crc_fn will be called only on the new bytes being tested, using as ‘’init’’ value the previously calculated CRC value. If false, crc_fn is always called on the full data interval, starting at begin.

  • valid_padding_bytes – An array of possible padding bytes values, by default just 0x00 and 0x80. Some ciphers prepend 0x80 before the zeroes.

Returns:

An iterator past-the-end of [message], i.e. an iterator to the first CRC byte (the last one of such iterators if multiple positions in the sequence have this property), and a boolean specifying whether the CRC checks out.