1 /* This file is in the public domain. */ 2 3 #include <sys/cdefs.h> 4 #include <opencrypto/xform_auth.h> 5 6 #include <sodium/crypto_onetimeauth_poly1305.h> 7 8 struct poly1305_xform_ctx { 9 struct crypto_onetimeauth_poly1305_state state; 10 }; 11 CTASSERT(sizeof(union authctx) >= sizeof(struct poly1305_xform_ctx)); 12 13 CTASSERT(POLY1305_KEY_LEN == crypto_onetimeauth_poly1305_KEYBYTES); 14 CTASSERT(POLY1305_HASH_LEN == crypto_onetimeauth_poly1305_BYTES); 15 CTASSERT(POLY1305_BLOCK_LEN == crypto_onetimeauth_poly1305_BYTES); 16 17 static void 18 xform_Poly1305_Init(void *polyctx) 19 { 20 /* Nop */ 21 } 22 23 static void 24 xform_Poly1305_Setkey(void *ctx, const uint8_t *key, u_int klen) 25 { 26 struct poly1305_xform_ctx *polyctx = ctx; 27 int rc; 28 29 if (klen != POLY1305_KEY_LEN) 30 panic("%s: Bogus keylen: %u bytes", __func__, (unsigned)klen); 31 32 rc = crypto_onetimeauth_poly1305_init(&polyctx->state, key); 33 if (rc != 0) 34 panic("%s: Invariant violated: %d", __func__, rc); 35 } 36 37 static int 38 xform_Poly1305_Update(void *ctx, const void *data, u_int len) 39 { 40 struct poly1305_xform_ctx *polyctx = ctx; 41 int rc; 42 43 rc = crypto_onetimeauth_poly1305_update(&polyctx->state, data, len); 44 if (rc != 0) 45 panic("%s: Invariant violated: %d", __func__, rc); 46 return (0); 47 } 48 49 static void 50 xform_Poly1305_Final(uint8_t *digest, void *ctx) 51 { 52 struct poly1305_xform_ctx *polyctx = ctx; 53 int rc; 54 55 rc = crypto_onetimeauth_poly1305_final(&polyctx->state, digest); 56 if (rc != 0) 57 panic("%s: Invariant violated: %d", __func__, rc); 58 } 59 60 const struct auth_hash auth_hash_poly1305 = { 61 .type = CRYPTO_POLY1305, 62 .name = "Poly-1305", 63 .keysize = POLY1305_KEY_LEN, 64 .hashsize = POLY1305_HASH_LEN, 65 .ctxsize = sizeof(struct poly1305_xform_ctx), 66 .blocksize = POLY1305_BLOCK_LEN, 67 .Init = xform_Poly1305_Init, 68 .Setkey = xform_Poly1305_Setkey, 69 .Update = xform_Poly1305_Update, 70 .Final = xform_Poly1305_Final, 71 }; 72