0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <crypto/internal/poly1305.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <asm/unaligned.h>
0014
0015 void poly1305_init_generic(struct poly1305_desc_ctx *desc,
0016 const u8 key[POLY1305_KEY_SIZE])
0017 {
0018 poly1305_core_setkey(&desc->core_r, key);
0019 desc->s[0] = get_unaligned_le32(key + 16);
0020 desc->s[1] = get_unaligned_le32(key + 20);
0021 desc->s[2] = get_unaligned_le32(key + 24);
0022 desc->s[3] = get_unaligned_le32(key + 28);
0023 poly1305_core_init(&desc->h);
0024 desc->buflen = 0;
0025 desc->sset = true;
0026 desc->rset = 2;
0027 }
0028 EXPORT_SYMBOL_GPL(poly1305_init_generic);
0029
0030 void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src,
0031 unsigned int nbytes)
0032 {
0033 unsigned int bytes;
0034
0035 if (unlikely(desc->buflen)) {
0036 bytes = min(nbytes, POLY1305_BLOCK_SIZE - desc->buflen);
0037 memcpy(desc->buf + desc->buflen, src, bytes);
0038 src += bytes;
0039 nbytes -= bytes;
0040 desc->buflen += bytes;
0041
0042 if (desc->buflen == POLY1305_BLOCK_SIZE) {
0043 poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf,
0044 1, 1);
0045 desc->buflen = 0;
0046 }
0047 }
0048
0049 if (likely(nbytes >= POLY1305_BLOCK_SIZE)) {
0050 poly1305_core_blocks(&desc->h, &desc->core_r, src,
0051 nbytes / POLY1305_BLOCK_SIZE, 1);
0052 src += nbytes - (nbytes % POLY1305_BLOCK_SIZE);
0053 nbytes %= POLY1305_BLOCK_SIZE;
0054 }
0055
0056 if (unlikely(nbytes)) {
0057 desc->buflen = nbytes;
0058 memcpy(desc->buf, src, nbytes);
0059 }
0060 }
0061 EXPORT_SYMBOL_GPL(poly1305_update_generic);
0062
0063 void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *dst)
0064 {
0065 if (unlikely(desc->buflen)) {
0066 desc->buf[desc->buflen++] = 1;
0067 memset(desc->buf + desc->buflen, 0,
0068 POLY1305_BLOCK_SIZE - desc->buflen);
0069 poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf, 1, 0);
0070 }
0071
0072 poly1305_core_emit(&desc->h, desc->s, dst);
0073 *desc = (struct poly1305_desc_ctx){};
0074 }
0075 EXPORT_SYMBOL_GPL(poly1305_final_generic);
0076
0077 MODULE_LICENSE("GPL");
0078 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");