/** * \file poly1305.c * * \brief Poly1305 authentication algorithm. * * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file is part of mbed TLS (https://tls.mbed.org) */ #include typedef struct mbedtls_poly1305_context { uint32_t r[4]; uint32_t s[4]; uint32_t acc[5]; } mbedtls_poly1305_context; void poly1305_compute_mac( const mbedtls_poly1305_context *ctx, unsigned char mac[16] ) { uint64_t d; uint32_t g0, g1, g2, g3, g4; uint32_t acc0, acc1, acc2, acc3, acc4; uint32_t mask; uint32_t mask_inv; acc0 = ctx->acc[0]; acc1 = ctx->acc[1]; acc2 = ctx->acc[2]; acc3 = ctx->acc[3]; acc4 = ctx->acc[4]; /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5. * We do this by calculating acc - (2^130 - 5), then checking if * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5) */ /* Calculate acc + -(2^130 - 5) */ d = ( (uint64_t) acc0 + 5U ); g0 = (uint32_t) d; d = ( (uint64_t) acc1 + ( d >> 32 ) ); g1 = (uint32_t) d; d = ( (uint64_t) acc2 + ( d >> 32 ) ); g2 = (uint32_t) d; d = ( (uint64_t) acc3 + ( d >> 32 ) ); g3 = (uint32_t) d; g4 = acc4 + (uint32_t) ( d >> 32U ); /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */ mask = (uint32_t) 0U - ( g4 >> 2U ); mask_inv = ~mask; /* If 131st bit is set then acc=g, otherwise, acc is unmodified */ acc0 = ( acc0 & mask_inv ) | ( g0 & mask ); acc1 = ( acc1 & mask_inv ) | ( g1 & mask ); acc2 = ( acc2 & mask_inv ) | ( g2 & mask ); acc3 = ( acc3 & mask_inv ) | ( g3 & mask ); /* Add 's' */ d = (uint64_t) acc0 + ctx->s[0]; acc0 = (uint32_t) d; d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U ); acc1 = (uint32_t) d; d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U ); acc2 = (uint32_t) d; acc3 += ctx->s[3] + (uint32_t) ( d >> 32U ); /* Compute MAC (128 least significant bits of the accumulator) */ mac[ 0] = (unsigned char)( acc0 ); mac[ 1] = (unsigned char)( acc0 >> 8 ); mac[ 2] = (unsigned char)( acc0 >> 16 ); mac[ 3] = (unsigned char)( acc0 >> 24 ); mac[ 4] = (unsigned char)( acc1 ); mac[ 5] = (unsigned char)( acc1 >> 8 ); mac[ 6] = (unsigned char)( acc1 >> 16 ); mac[ 7] = (unsigned char)( acc1 >> 24 ); mac[ 8] = (unsigned char)( acc2 ); mac[ 9] = (unsigned char)( acc2 >> 8 ); mac[10] = (unsigned char)( acc2 >> 16 ); mac[11] = (unsigned char)( acc2 >> 24 ); mac[12] = (unsigned char)( acc3 ); mac[13] = (unsigned char)( acc3 >> 8 ); mac[14] = (unsigned char)( acc3 >> 16 ); mac[15] = (unsigned char)( acc3 >> 24 ); }