unsigned char *c, uint32_t bytes);
#endif /* CHACHA_H */
-
return res;
}
-/**
- * Poly1305 tag generation. This concatenates a string according to the rules
- * outlined in RFC 7539 and calculates the tag.
- *
- * \param poly_key 32 byte secret one-time key for poly1305
- * \param ad associated data
- * \param ad_len associated data length in bytes
- * \param ct ciphertext
- * \param ct_len ciphertext length in bytes
- * \param tag pointer to 16 bytes for tag storage
- */
-static void poly1305_get_tag(unsigned char *poly_key, const void *ad,
- int ad_len, const void *ct, int ct_len, unsigned char *tag) {
- struct poly1305_context poly;
- unsigned left_over;
- uint64_t len;
- unsigned char pad[16];
-
- poly1305_init(&poly, poly_key);
- memset(&pad, 0, sizeof(pad));
-
- /* associated data and padding */
- poly1305_update(&poly, ad, ad_len);
- left_over = ad_len % 16;
-
- if(left_over) {
- poly1305_update(&poly, pad, 16 - left_over);
- }
-
- /* payload and padding */
- poly1305_update(&poly, ct, ct_len);
- left_over = ct_len % 16;
-
- if(left_over) {
- poly1305_update(&poly, pad, 16 - left_over);
- }
-
- /* lengths */
- len = ad_len;
- poly1305_update(&poly, (unsigned char *)&len, 8);
- len = ct_len;
- poly1305_update(&poly, (unsigned char *)&len, 8);
-
- poly1305_finish(&poly, tag);
-}
-
int chachapoly_init(struct chachapoly_ctx *ctx, const void *key, int key_len) {
assert(key_len == 128 || key_len == 256);
}
int chachapoly_crypt(struct chachapoly_ctx *ctx, const void *nonce,
- const void *ad, int ad_len, void *input, int input_len,
+ void *input, int input_len,
void *output, void *tag, int tag_len, int encrypt) {
unsigned char poly_key[CHACHA_BLOCKLEN];
unsigned char calc_tag[POLY1305_TAGLEN];
/* check tag if decrypting */
if(encrypt == 0 && tag_len) {
- poly1305_get_tag(poly_key, ad, ad_len, input, input_len, calc_tag);
+ poly1305_get_tag(poly_key, input, input_len, calc_tag);
if(memcmp_eq(calc_tag, tag, tag_len) != 0) {
return CHACHAPOLY_INVALID_MAC;
/* add tag if encrypting */
if(encrypt && tag_len) {
- poly1305_get_tag(poly_key, ad, ad_len, output, input_len, calc_tag);
+ poly1305_get_tag(poly_key, output, input_len, calc_tag);
memcpy(tag, calc_tag, tag_len);
}
}
int chachapoly_crypt_short(struct chachapoly_ctx *ctx, const void *nonce,
- const void *ad, int ad_len, void *input, int input_len,
+ void *input, int input_len,
void *output, void *tag, int tag_len, int encrypt) {
unsigned char keystream[CHACHA_BLOCKLEN];
unsigned char calc_tag[POLY1305_TAGLEN];
/* check tag if decrypting */
if(encrypt == 0 && tag_len) {
- poly1305_get_tag(keystream, ad, ad_len, input, input_len, calc_tag);
+ poly1305_get_tag(keystream, input, input_len, calc_tag);
if(memcmp_eq(calc_tag, tag, tag_len) != 0) {
return CHACHAPOLY_INVALID_MAC;
/* add tag if encrypting */
if(encrypt && tag_len) {
- poly1305_get_tag(keystream, ad, ad_len, output, input_len, calc_tag);
+ poly1305_get_tag(keystream, output, input_len, calc_tag);
memcpy(tag, calc_tag, tag_len);
}
*
* \param ctx context data
* \param nonce nonce (12 bytes)
- * \param ad associated data
- * \param ad_len associated data length in bytes
* \param input plaintext/ciphertext input
* \param input_len input length in bytes;
* \param output plaintext/ciphertext output
* failed when decrypting
*/
int chachapoly_crypt(struct chachapoly_ctx *ctx, const void *nonce,
- const void *ad, int ad_len, void *input, int input_len,
+ void *input, int input_len,
void *output, void *tag, int tag_len, int encrypt);
/**
* chachapoly_crypt.
*/
int chachapoly_crypt_short(struct chachapoly_ctx *ctx, const void *nonce,
- const void *ad, int ad_len, void *input, int input_len,
+ void *input, int input_len,
void *output, void *tag, int tag_len, int encrypt);
#endif
#include "poly1305.h"
+/* use memcpy() to copy blocks of memory (typically faster) */
+#define USE_MEMCPY 1
+/* use unaligned little-endian load/store (can be faster) */
+#define USE_UNALIGNED 0
+
+struct poly1305_context {
+ uint32_t r[5];
+ uint32_t h[5];
+ uint32_t pad[4];
+ size_t leftover;
+ unsigned char buffer[POLY1305_BLOCK_SIZE];
+ unsigned char final;
+};
+
#if (USE_UNALIGNED == 1)
#define U8TO32(p) \
(*((uint32_t *)(p)))
}
#endif
-void
+static void
poly1305_init(struct poly1305_context *st, const unsigned char key[32]) {
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
st->r[0] = (U8TO32(&key[ 0])) & 0x3ffffff;
st->h[4] = h4;
}
-void
+static void
poly1305_finish(struct poly1305_context *st, unsigned char mac[16]) {
uint32_t h0, h1, h2, h3, h4, c;
uint32_t g0, g1, g2, g3, g4;
st->pad[3] = 0;
}
-
-void
+static void
poly1305_update(struct poly1305_context *st, const unsigned char *m, size_t bytes) {
size_t i;
}
}
+/**
+ * Poly1305 tag generation. This concatenates a string according to the rules
+ * outlined in RFC 7539 and calculates the tag.
+ *
+ * \param key 32 byte secret one-time key for poly1305
+ * \param ct ciphertext
+ * \param ct_len ciphertext length in bytes
+ * \param tag pointer to 16 bytes for tag storage
+ */
void
-poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]) {
+poly1305_get_tag(const unsigned char key[32], const void *ct, int ct_len, unsigned char tag[16]) {
struct poly1305_context ctx;
+ unsigned left_over;
+ uint64_t len;
+ unsigned char pad[16];
+
poly1305_init(&ctx, key);
- poly1305_update(&ctx, m, bytes);
- poly1305_finish(&ctx, mac);
+ memset(&pad, 0, sizeof(pad));
+
+ /* payload and padding */
+ poly1305_update(&ctx, ct, ct_len);
+ left_over = ct_len % 16;
+
+ if(left_over) {
+ poly1305_update(&ctx, pad, 16 - left_over);
+ }
+
+ /* lengths */
+ len = 0;
+ poly1305_update(&ctx, (unsigned char *)&len, 8);
+ len = ct_len;
+ poly1305_update(&ctx, (unsigned char *)&len, 8);
+ poly1305_finish(&ctx, tag);
}
#define POLY1305_TAGLEN 16
#define POLY1305_BLOCK_SIZE 16
-/* use memcpy() to copy blocks of memory (typically faster) */
-#define USE_MEMCPY 1
-/* use unaligned little-endian load/store (can be faster) */
-#define USE_UNALIGNED 0
-
-struct poly1305_context {
- uint32_t r[5];
- uint32_t h[5];
- uint32_t pad[4];
- size_t leftover;
- unsigned char buffer[POLY1305_BLOCK_SIZE];
- unsigned char final;
-};
-
-void poly1305_init(struct poly1305_context *ctx, const unsigned char key[32]);
-void poly1305_update(struct poly1305_context *ctx, const unsigned char *m, size_t bytes);
-void poly1305_finish(struct poly1305_context *ctx, unsigned char mac[16]);
-void poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]);
+void poly1305_get_tag(const unsigned char key[32], const void *ct, int ct_len, unsigned char tag[16]);
#endif /* POLY1305_H */
-
#ifndef HAVE_OPENSSL
case SPTPS_CHACHA_POLY1305: {
- if(chachapoly_crypt(ctx, nonce, NULL, 0, (void *)in, inlen, out, out + inlen, 16, 1) != CHACHAPOLY_OK) {
+ if(chachapoly_crypt(ctx, nonce, (void *)in, inlen, out, out + inlen, 16, 1) != CHACHAPOLY_OK) {
return false;
}
#ifndef HAVE_OPENSSL
case SPTPS_CHACHA_POLY1305:
- if(chachapoly_crypt(ctx, nonce, NULL, 0, (void *)in, inlen, out, (void *)(in + inlen), 16, 0) != CHACHAPOLY_OK) {
+ if(chachapoly_crypt(ctx, nonce, (void *)in, inlen, out, (void *)(in + inlen), 16, 0) != CHACHAPOLY_OK) {
return false;
}