/* ====================================================================
* Copyright (c) 2015 The OpenSSL Project. All rights reserved.
*
* Rights for redistribution and usage in source and binary
* forms are granted according to the OpenSSL license.
*/
#include <stdlib.h>
#include <string.h>
#include "internal/poly1305.h"
typedef void (*poly1305_blocks_f) (void *ctx, const unsigned char *inp,
size_t len, unsigned int padbit);
typedef void (*poly1305_emit_f) (void *ctx, unsigned char mac[16],
const unsigned int nonce[4]);
struct poly1305_context {
double opaque[24]; /* large enough to hold internal state, declared
* 'double' to ensure at least 64-bit invariant
* alignment across all platforms and
* configurations */
unsigned int nonce[4];
unsigned char data[POLY1305_BLOCK_SIZE];
size_t num;
struct {
poly1305_blocks_f blocks;
poly1305_emit_f emit;
} func;
};
size_t Poly1305_ctx_size ()
{
return sizeof(struct poly1305_context);
}
/* pick 32-bit unsigned integer in little endian order */
static unsigned int U8TOU32(const unsigned char *p)
{
return (((unsigned int)(p[0] & 0xff)) |
((unsigned int)(p[1] & 0xff) << 8) |
((unsigned int)(p[2] & 0xff) << 16) |
((unsigned int)(p[3] & 0xff) << 24));
}
/*
* Implementations can be classified by amount of significant bits in
* words making up the multi-precision value, or in other words radix
* or base of numerical representation, e.g. base 2^64, base 2^32,
* base 2^26. Complementary characteristic is how wide is the result of
* multiplication of pair of digits, e.g. it would take 128 bits to
* accommodate multiplication result in base 2^64 case. These are used
* interchangeably. To describe implementation that is. But interface
* is designed to isolate this so that low-level primitives implemented
* in assembly can be self-contained/self-coherent.
*/
#ifndef POLY1305_ASM
/*
* Even though there is __int128 reference implementation targeting
* 64-bit platforms provided below, it's not obvious that it's optimal
* choice for every one of them. Depending on instruction set overall
* amount of instructions can be comparable to one in __int64
* implementation. Amount of multiplication instructions would be lower,
* but not necessarily overall. And in out-of-order execution context,
* it is the latter that can be crucial...
*
* On related note. Poly1305 author, D. J. Bernstein, discusses and
* provides floating-point implementations of the algorithm in question.
* It made a lot of sense by the time of introduction, because most
* then-modern processors didn't have pipelined integer multiplier.
* [Not to mention that some had non-constant timing for integer
* multiplications.] Floating-point instructions on the other hand could
* be issued every cycle, which allowed to achieve better performance.
* Nowadays, with SIMD and/or out-or-order execution, shared or
* even emulated FPU, it's more complicated, and floating-point
* implementation is not necessarily optimal choice in every situation,
* rather contrary...
*
* <appro@openssl.org>
*/
typedef unsigned int u32;
/*
* poly1305_blocks processes a multiple of POLY1305_BLOCK_SIZE blocks
* of |inp| no longer than |len|. Behaviour for |len| not divisible by
* block size is unspecified in general case, even though in reference
* implementation the trailing chunk is simply ignored. Per algorithm
* specification, every input block, complete or last partial, is to be
* padded with a bit past most significant byte. The latter kind is then
* padded with zeros till block size. This last partial block padding
* is caller(*)'s responsibility, and because of this the last partial
* block is always processed with separate call with |len| set to
* POLY1305_BLOCK_SIZE and |padbit| to 0. In all other cases |padbit|
* should be set to 1 to perform implicit padding with 128th bit.
* poly1305_blocks does not actually check for this constraint though,
* it's caller(*)'s responsibility to comply.
*
* (*) In the context "caller" is not application code, but higher
* level Poly1305_* from this very module, so that quirks are
* handled locally.
*/
static void
poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, u32 padbit);
/*
* Type-agnostic "rip-off" from constant_time_locl.h
*/
# define CONSTANT_TIME_CARRY(a,b) ( \
(a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1) \
)
# if !defined(PEDANTIC) && \
(defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16) && \
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__==8)
typedef unsigned long u64;
typedef unsigned __int128 u128;
typedef struct {
u64 h[3];
u64 r[2];
} poly1305_internal;
/* pick 32-bit unsigned integer in little endian order */
static u64 U8TOU64(const unsigned char *p)
{
return (((u64)(p[0] & 0xff)) |
((u64)(p[1] & 0xff) << 8) |
((u64)(p[2] & 0xff) << 16) |
((u64)(p[3] & 0xff) << 24) |
((u64)(p[4] & 0xff) << 32) |
((u64)(p[5] & 0xff) << 40) |
((u64)(p[6] & 0xff) << 48) |
((u64)(p[7] & 0xff) << 56));
}
/* store a 32-bit unsigned integer in little endian */
static void U64TO8(unsigned char *p, u64 v)