mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-17 02:36:21 +00:00
crypto: poly1305 - Export common Poly1305 helpers
As architecture specific drivers need a software fallback, export Poly1305 init/update/final functions together with some helpers in a header file. Signed-off-by: Martin Willi <martin@strongswan.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
6692cbc28e
commit
2546f811ef
@ -14,6 +14,7 @@
|
|||||||
#include <crypto/internal/skcipher.h>
|
#include <crypto/internal/skcipher.h>
|
||||||
#include <crypto/scatterwalk.h>
|
#include <crypto/scatterwalk.h>
|
||||||
#include <crypto/chacha20.h>
|
#include <crypto/chacha20.h>
|
||||||
|
#include <crypto/poly1305.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@ -21,9 +22,6 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define POLY1305_BLOCK_SIZE 16
|
|
||||||
#define POLY1305_DIGEST_SIZE 16
|
|
||||||
#define POLY1305_KEY_SIZE 32
|
|
||||||
#define CHACHAPOLY_IV_SIZE 12
|
#define CHACHAPOLY_IV_SIZE 12
|
||||||
|
|
||||||
struct chachapoly_instance_ctx {
|
struct chachapoly_instance_ctx {
|
||||||
|
@ -13,31 +13,11 @@
|
|||||||
|
|
||||||
#include <crypto/algapi.h>
|
#include <crypto/algapi.h>
|
||||||
#include <crypto/internal/hash.h>
|
#include <crypto/internal/hash.h>
|
||||||
|
#include <crypto/poly1305.h>
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#define POLY1305_BLOCK_SIZE 16
|
|
||||||
#define POLY1305_KEY_SIZE 32
|
|
||||||
#define POLY1305_DIGEST_SIZE 16
|
|
||||||
|
|
||||||
struct poly1305_desc_ctx {
|
|
||||||
/* key */
|
|
||||||
u32 r[5];
|
|
||||||
/* finalize key */
|
|
||||||
u32 s[4];
|
|
||||||
/* accumulator */
|
|
||||||
u32 h[5];
|
|
||||||
/* partial buffer */
|
|
||||||
u8 buf[POLY1305_BLOCK_SIZE];
|
|
||||||
/* bytes used in partial buffer */
|
|
||||||
unsigned int buflen;
|
|
||||||
/* r key has been set */
|
|
||||||
bool rset;
|
|
||||||
/* s key has been set */
|
|
||||||
bool sset;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline u64 mlt(u64 a, u64 b)
|
static inline u64 mlt(u64 a, u64 b)
|
||||||
{
|
{
|
||||||
return a * b;
|
return a * b;
|
||||||
@ -58,7 +38,7 @@ static inline u32 le32_to_cpuvp(const void *p)
|
|||||||
return le32_to_cpup(p);
|
return le32_to_cpup(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int poly1305_init(struct shash_desc *desc)
|
int crypto_poly1305_init(struct shash_desc *desc)
|
||||||
{
|
{
|
||||||
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||||
|
|
||||||
@ -69,8 +49,9 @@ static int poly1305_init(struct shash_desc *desc)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(crypto_poly1305_init);
|
||||||
|
|
||||||
static int poly1305_setkey(struct crypto_shash *tfm,
|
int crypto_poly1305_setkey(struct crypto_shash *tfm,
|
||||||
const u8 *key, unsigned int keylen)
|
const u8 *key, unsigned int keylen)
|
||||||
{
|
{
|
||||||
/* Poly1305 requires a unique key for each tag, which implies that
|
/* Poly1305 requires a unique key for each tag, which implies that
|
||||||
@ -79,6 +60,7 @@ static int poly1305_setkey(struct crypto_shash *tfm,
|
|||||||
* the update() call. */
|
* the update() call. */
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(crypto_poly1305_setkey);
|
||||||
|
|
||||||
static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key)
|
static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key)
|
||||||
{
|
{
|
||||||
@ -98,16 +80,10 @@ static void poly1305_setskey(struct poly1305_desc_ctx *dctx, const u8 *key)
|
|||||||
dctx->s[3] = le32_to_cpuvp(key + 12);
|
dctx->s[3] = le32_to_cpuvp(key + 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
|
unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
|
||||||
const u8 *src, unsigned int srclen,
|
const u8 *src, unsigned int srclen)
|
||||||
u32 hibit)
|
|
||||||
{
|
{
|
||||||
u32 r0, r1, r2, r3, r4;
|
if (!dctx->sset) {
|
||||||
u32 s1, s2, s3, s4;
|
|
||||||
u32 h0, h1, h2, h3, h4;
|
|
||||||
u64 d0, d1, d2, d3, d4;
|
|
||||||
|
|
||||||
if (unlikely(!dctx->sset)) {
|
|
||||||
if (!dctx->rset && srclen >= POLY1305_BLOCK_SIZE) {
|
if (!dctx->rset && srclen >= POLY1305_BLOCK_SIZE) {
|
||||||
poly1305_setrkey(dctx, src);
|
poly1305_setrkey(dctx, src);
|
||||||
src += POLY1305_BLOCK_SIZE;
|
src += POLY1305_BLOCK_SIZE;
|
||||||
@ -121,6 +97,25 @@ static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
|
|||||||
dctx->sset = true;
|
dctx->sset = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return srclen;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(crypto_poly1305_setdesckey);
|
||||||
|
|
||||||
|
static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
|
||||||
|
const u8 *src, unsigned int srclen,
|
||||||
|
u32 hibit)
|
||||||
|
{
|
||||||
|
u32 r0, r1, r2, r3, r4;
|
||||||
|
u32 s1, s2, s3, s4;
|
||||||
|
u32 h0, h1, h2, h3, h4;
|
||||||
|
u64 d0, d1, d2, d3, d4;
|
||||||
|
unsigned int datalen;
|
||||||
|
|
||||||
|
if (unlikely(!dctx->sset)) {
|
||||||
|
datalen = crypto_poly1305_setdesckey(dctx, src, srclen);
|
||||||
|
src += srclen - datalen;
|
||||||
|
srclen = datalen;
|
||||||
|
}
|
||||||
|
|
||||||
r0 = dctx->r[0];
|
r0 = dctx->r[0];
|
||||||
r1 = dctx->r[1];
|
r1 = dctx->r[1];
|
||||||
@ -181,7 +176,7 @@ static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
|
|||||||
return srclen;
|
return srclen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int poly1305_update(struct shash_desc *desc,
|
int crypto_poly1305_update(struct shash_desc *desc,
|
||||||
const u8 *src, unsigned int srclen)
|
const u8 *src, unsigned int srclen)
|
||||||
{
|
{
|
||||||
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||||
@ -214,8 +209,9 @@ static int poly1305_update(struct shash_desc *desc,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(crypto_poly1305_update);
|
||||||
|
|
||||||
static int poly1305_final(struct shash_desc *desc, u8 *dst)
|
int crypto_poly1305_final(struct shash_desc *desc, u8 *dst)
|
||||||
{
|
{
|
||||||
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||||
__le32 *mac = (__le32 *)dst;
|
__le32 *mac = (__le32 *)dst;
|
||||||
@ -282,13 +278,14 @@ static int poly1305_final(struct shash_desc *desc, u8 *dst)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(crypto_poly1305_final);
|
||||||
|
|
||||||
static struct shash_alg poly1305_alg = {
|
static struct shash_alg poly1305_alg = {
|
||||||
.digestsize = POLY1305_DIGEST_SIZE,
|
.digestsize = POLY1305_DIGEST_SIZE,
|
||||||
.init = poly1305_init,
|
.init = crypto_poly1305_init,
|
||||||
.update = poly1305_update,
|
.update = crypto_poly1305_update,
|
||||||
.final = poly1305_final,
|
.final = crypto_poly1305_final,
|
||||||
.setkey = poly1305_setkey,
|
.setkey = crypto_poly1305_setkey,
|
||||||
.descsize = sizeof(struct poly1305_desc_ctx),
|
.descsize = sizeof(struct poly1305_desc_ctx),
|
||||||
.base = {
|
.base = {
|
||||||
.cra_name = "poly1305",
|
.cra_name = "poly1305",
|
||||||
|
41
include/crypto/poly1305.h
Normal file
41
include/crypto/poly1305.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Common values for the Poly1305 algorithm
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CRYPTO_POLY1305_H
|
||||||
|
#define _CRYPTO_POLY1305_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/crypto.h>
|
||||||
|
|
||||||
|
#define POLY1305_BLOCK_SIZE 16
|
||||||
|
#define POLY1305_KEY_SIZE 32
|
||||||
|
#define POLY1305_DIGEST_SIZE 16
|
||||||
|
|
||||||
|
struct poly1305_desc_ctx {
|
||||||
|
/* key */
|
||||||
|
u32 r[5];
|
||||||
|
/* finalize key */
|
||||||
|
u32 s[4];
|
||||||
|
/* accumulator */
|
||||||
|
u32 h[5];
|
||||||
|
/* partial buffer */
|
||||||
|
u8 buf[POLY1305_BLOCK_SIZE];
|
||||||
|
/* bytes used in partial buffer */
|
||||||
|
unsigned int buflen;
|
||||||
|
/* r key has been set */
|
||||||
|
bool rset;
|
||||||
|
/* s key has been set */
|
||||||
|
bool sset;
|
||||||
|
};
|
||||||
|
|
||||||
|
int crypto_poly1305_init(struct shash_desc *desc);
|
||||||
|
int crypto_poly1305_setkey(struct crypto_shash *tfm,
|
||||||
|
const u8 *key, unsigned int keylen);
|
||||||
|
unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
|
||||||
|
const u8 *src, unsigned int srclen);
|
||||||
|
int crypto_poly1305_update(struct shash_desc *desc,
|
||||||
|
const u8 *src, unsigned int srclen);
|
||||||
|
int crypto_poly1305_final(struct shash_desc *desc, u8 *dst);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user