~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/crypto/poly1305_generic.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Poly1305 authenticator algorithm, RFC7539
  3  *
  4  * Copyright (C) 2015 Martin Willi
  5  *
  6  * Based on public domain code by Andrew Moon and Daniel J. Bernstein.
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU General Public License as published by
 10  * the Free Software Foundation; either version 2 of the License, or
 11  * (at your option) any later version.
 12  */
 13 
 14 #include <crypto/algapi.h>
 15 #include <crypto/internal/hash.h>
 16 #include <crypto/internal/poly1305.h>
 17 #include <linux/crypto.h>
 18 #include <linux/kernel.h>
 19 #include <linux/module.h>
 20 #include <asm/unaligned.h>
 21 
 22 static int crypto_poly1305_init(struct shash_desc *desc)
 23 {
 24         struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
 25 
 26         poly1305_core_init(&dctx->h);
 27         dctx->buflen = 0;
 28         dctx->rset = 0;
 29         dctx->sset = false;
 30 
 31         return 0;
 32 }
 33 
 34 static unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
 35                                                const u8 *src, unsigned int srclen)
 36 {
 37         if (!dctx->sset) {
 38                 if (!dctx->rset && srclen >= POLY1305_BLOCK_SIZE) {
 39                         poly1305_core_setkey(&dctx->core_r, src);
 40                         src += POLY1305_BLOCK_SIZE;
 41                         srclen -= POLY1305_BLOCK_SIZE;
 42                         dctx->rset = 2;
 43                 }
 44                 if (srclen >= POLY1305_BLOCK_SIZE) {
 45                         dctx->s[0] = get_unaligned_le32(src +  0);
 46                         dctx->s[1] = get_unaligned_le32(src +  4);
 47                         dctx->s[2] = get_unaligned_le32(src +  8);
 48                         dctx->s[3] = get_unaligned_le32(src + 12);
 49                         src += POLY1305_BLOCK_SIZE;
 50                         srclen -= POLY1305_BLOCK_SIZE;
 51                         dctx->sset = true;
 52                 }
 53         }
 54         return srclen;
 55 }
 56 
 57 static void poly1305_blocks(struct poly1305_desc_ctx *dctx, const u8 *src,
 58                             unsigned int srclen)
 59 {
 60         unsigned int datalen;
 61 
 62         if (unlikely(!dctx->sset)) {
 63                 datalen = crypto_poly1305_setdesckey(dctx, src, srclen);
 64                 src += srclen - datalen;
 65                 srclen = datalen;
 66         }
 67 
 68         poly1305_core_blocks(&dctx->h, &dctx->core_r, src,
 69                              srclen / POLY1305_BLOCK_SIZE, 1);
 70 }
 71 
 72 static int crypto_poly1305_update(struct shash_desc *desc,
 73                                   const u8 *src, unsigned int srclen)
 74 {
 75         struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
 76         unsigned int bytes;
 77 
 78         if (unlikely(dctx->buflen)) {
 79                 bytes = min(srclen, POLY1305_BLOCK_SIZE - dctx->buflen);
 80                 memcpy(dctx->buf + dctx->buflen, src, bytes);
 81                 src += bytes;
 82                 srclen -= bytes;
 83                 dctx->buflen += bytes;
 84 
 85                 if (dctx->buflen == POLY1305_BLOCK_SIZE) {
 86                         poly1305_blocks(dctx, dctx->buf,
 87                                         POLY1305_BLOCK_SIZE);
 88                         dctx->buflen = 0;
 89                 }
 90         }
 91 
 92         if (likely(srclen >= POLY1305_BLOCK_SIZE)) {
 93                 poly1305_blocks(dctx, src, srclen);
 94                 src += srclen - (srclen % POLY1305_BLOCK_SIZE);
 95                 srclen %= POLY1305_BLOCK_SIZE;
 96         }
 97 
 98         if (unlikely(srclen)) {
 99                 dctx->buflen = srclen;
100                 memcpy(dctx->buf, src, srclen);
101         }
102 
103         return 0;
104 }
105 
106 static int crypto_poly1305_final(struct shash_desc *desc, u8 *dst)
107 {
108         struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
109 
110         if (unlikely(!dctx->sset))
111                 return -ENOKEY;
112 
113         poly1305_final_generic(dctx, dst);
114         return 0;
115 }
116 
117 static struct shash_alg poly1305_alg = {
118         .digestsize     = POLY1305_DIGEST_SIZE,
119         .init           = crypto_poly1305_init,
120         .update         = crypto_poly1305_update,
121         .final          = crypto_poly1305_final,
122         .descsize       = sizeof(struct poly1305_desc_ctx),
123         .base           = {
124                 .cra_name               = "poly1305",
125                 .cra_driver_name        = "poly1305-generic",
126                 .cra_priority           = 100,
127                 .cra_blocksize          = POLY1305_BLOCK_SIZE,
128                 .cra_module             = THIS_MODULE,
129         },
130 };
131 
132 static int __init poly1305_mod_init(void)
133 {
134         return crypto_register_shash(&poly1305_alg);
135 }
136 
137 static void __exit poly1305_mod_exit(void)
138 {
139         crypto_unregister_shash(&poly1305_alg);
140 }
141 
142 subsys_initcall(poly1305_mod_init);
143 module_exit(poly1305_mod_exit);
144 
145 MODULE_LICENSE("GPL");
146 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");
147 MODULE_DESCRIPTION("Poly1305 authenticator");
148 MODULE_ALIAS_CRYPTO("poly1305");
149 MODULE_ALIAS_CRYPTO("poly1305-generic");
150 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php