1 /* 2 * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef POLY_H 8 #define POLY_H 9 10 /* 11 * All the includes that are needed for code using this module to 12 * compile correctly should be #included here. 13 */ 14 #include <stdint.h> 15 #include "cc_error.h" 16 #include "mbedtls_cc_poly.h" 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 /*! The POLY block size in 32-bit words */ 23 #define CC_POLY_BLOCK_SIZE_IN_WORDS 4 24 #define CC_POLY_BLOCK_SIZE_IN_BYTES (CC_POLY_BLOCK_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE) 25 26 #define POLY_PRIME_SIZE_IN_BITS 130 27 #define POLY_PRIME_SIZE_IN_WORDS CALC_FULL_32BIT_WORDS(POLY_PRIME_SIZE_IN_BITS) 28 29 /*! The POLY PKA registers size in 32-bit words */ 30 #define CC_POLY_PKA_REG_SIZE_IN_PKA_WORDS 4 31 #define CC_POLY_PKA_REG_SIZE_IN_WORDS (CC_POLY_PKA_REG_SIZE_IN_PKA_WORDS * (CALC_FULL_32BIT_WORDS(CC_PKA_WORD_SIZE_IN_BITS))) 32 #define CC_POLY_PKA_REG_SIZE_IN_BYTES (CC_POLY_PKA_REG_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE) 33 34 /** 35 * PKA register contexts. Between multipart calls, the PKA engine needs to save 36 * and restore the register context. It's composed of the clamped key pair 37 * (r,s) 256 bit long and the value of the accumulator register which is mod P, 38 * where P is 2^130-5, which in full words is 160 bit long, 5 32-bit words. 39 */ 40 typedef struct PolyPkaContext { 41 uint32_t key[8]; /*!< (r,s) concatenated with r already clamped */ 42 uint32_t acc[5]; /*!< Value of the accumulator modulus P, i.e. [0,2^130-5)*/ 43 } PolyPkaContext_t; 44 45 /** 46 * State information required to support multipart APIs in AEAD for MAC 47 * computation. As Poly1305 operates on CC_POLY_BLOCK_SIZE_IN BYTES of data 48 * it needs to cache up to CC_POLY_BLOCK_SIZE_IN_BYTES-1 of the input. But 49 * for practical reasons (i.e. working on 4-byte aligned buffers) we store an 50 * entire block of 16 bytes that can be processed in one go without additional 51 * copies 52 */ 53 typedef struct PolyState { 54 uint32_t msg_state[CC_POLY_BLOCK_SIZE_IN_WORDS]; /*!< Equals 16 bytes of 55 * data 56 */ 57 uint8_t msg_state_size; /*!< Size of the message buffered in msg_state */ 58 PolyPkaContext_t context; /*!< PKA registers context (clamped key, acc) */ 59 } PolyState_t; 60 61 /** 62 * @brief Generates the POLY mac according to RFC 7539 section 2.5.1 63 * 64 * @param[in] key Pointer to 256 bits of KEY. 65 * @param[in] pAddData Optional - pointer to additional data if any 66 * @param[in] addDataSize The size of the additional data 67 * @param[in] pDataIn Pointer to data buffer to calculate MAC on 68 * @param[in] dataInSize The size of the additional data 69 * @param[out] macRes The calculated MAC 70 * @param[in] isPolyAeadMode Boolean indicating if the Poly MAC operation is 71 * part of AEAD or just poly. In AEAD mode, the 72 * last block of AddData and DataIn accumulation 73 * will be padded with zeros up to 16 bytes as per 74 * the AEAD spec construction on RFC7539. 75 * 76 * @return CC_OK On success, otherwise indicates failure 77 */ 78 CCError_t PolyMacCalc(mbedtls_poly_key key, 79 const uint8_t *pAddData, 80 size_t addDataSize, 81 const uint8_t *pDataIn, 82 size_t dataInSize, 83 mbedtls_poly_mac macRes, 84 bool isPolyAeadMode); 85 86 /** 87 * @brief Initialises a multipart authentication. 88 * 89 * @param[in,out] state Pointer to the state associated to the operation. 90 * @param[in,out] key Buffer containing the (r,s) keypair. 91 * @param[in] key_size Size in bytes of the key. Must be 32 bytes. 92 * 93 * @return It returns CC_OK on success, or an error code otherwise 94 */ 95 CCError_t PolyInit(PolyState_t *state, const uint8_t *key, size_t key_size); 96 97 /** 98 * @brief Updates a pre-initialised multipart authentication with a new 99 * chunk of data to be authenticated. 100 * 101 * @param[in,out] state Pointer to the state associated to the operation. 102 * @param[in] data Buffer containing the data to be authenticated. 103 * @param[in] data_size Size in bytes of the data to be authenticated. 104 * @param[in] isPolyAeadMode Boolean indicating if the update is the last 105 * of an AEAD operation. In that case, it will pad 106 * the last partial block with zeros to make a 107 * full block as specified on RFC7539. 108 * 109 * @return It returns CC_OK on success, or an error code otherwise 110 */ 111 CCError_t PolyUpdate(PolyState_t *state, 112 const uint8_t *data, 113 size_t data_size, 114 bool isPolyAeadMode); 115 116 /** 117 * @brief Finalises a pre-initialised multipart authentication outputting 118 * the 16 bytes that make the Poly1305 tag. 119 * 120 * @param[in,out] state Pointer to the state associated to the operation. 121 * @param[out] tag Buffer that will contain the 16 bytes of the tag. 122 * @param[in] tag_size Size in bytes ot the tag buffer. It needs to be 123 * at least 16 bytes, i.e. CC_POLY_BLOCK_SIZE_IN_BYTES 124 * 125 * @return It returns CC_OK on success, or an error code otherwise 126 */ 127 CCError_t PolyFinish(PolyState_t *state, uint8_t *tag, size_t tag_size); 128 129 #ifdef __cplusplus 130 } 131 #endif 132 133 #endif /* POLY_H */ 134