mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
crypto: lib/poly1305 - Add block-only interface
Add a block-only interface for poly1305. Implement the generic code first. Also use the generic partial block helper. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
74a43a2cf5
commit
9b84cb8978
3 changed files with 68 additions and 39 deletions
|
@ -6,9 +6,8 @@
|
|||
#ifndef _CRYPTO_INTERNAL_POLY1305_H
|
||||
#define _CRYPTO_INTERNAL_POLY1305_H
|
||||
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/poly1305.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* Poly1305 core functions. These only accept whole blocks; the caller must
|
||||
|
@ -31,4 +30,29 @@ void poly1305_core_blocks(struct poly1305_state *state,
|
|||
void poly1305_core_emit(const struct poly1305_state *state, const u32 nonce[4],
|
||||
void *dst);
|
||||
|
||||
void poly1305_block_init_arch(struct poly1305_block_state *state,
|
||||
const u8 raw_key[POLY1305_BLOCK_SIZE]);
|
||||
void poly1305_block_init_generic(struct poly1305_block_state *state,
|
||||
const u8 raw_key[POLY1305_BLOCK_SIZE]);
|
||||
void poly1305_blocks_arch(struct poly1305_block_state *state, const u8 *src,
|
||||
unsigned int len, u32 padbit);
|
||||
|
||||
static inline void poly1305_blocks_generic(struct poly1305_block_state *state,
|
||||
const u8 *src, unsigned int len,
|
||||
u32 padbit)
|
||||
{
|
||||
poly1305_core_blocks(&state->h, &state->core_r, src,
|
||||
len / POLY1305_BLOCK_SIZE, padbit);
|
||||
}
|
||||
|
||||
void poly1305_emit_arch(const struct poly1305_state *state,
|
||||
u8 digest[POLY1305_DIGEST_SIZE], const u32 nonce[4]);
|
||||
|
||||
static inline void poly1305_emit_generic(const struct poly1305_state *state,
|
||||
u8 digest[POLY1305_DIGEST_SIZE],
|
||||
const u32 nonce[4])
|
||||
{
|
||||
poly1305_core_emit(state, nonce, digest);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#define _CRYPTO_POLY1305_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/crypto.h>
|
||||
|
||||
#define POLY1305_BLOCK_SIZE 16
|
||||
#define POLY1305_KEY_SIZE 32
|
||||
|
@ -38,6 +37,17 @@ struct poly1305_state {
|
|||
};
|
||||
};
|
||||
|
||||
/* Combined state for block function. */
|
||||
struct poly1305_block_state {
|
||||
/* accumulator */
|
||||
struct poly1305_state h;
|
||||
/* key */
|
||||
union {
|
||||
struct poly1305_key opaque_r[CONFIG_CRYPTO_LIB_POLY1305_RSIZE];
|
||||
struct poly1305_core_key core_r;
|
||||
};
|
||||
};
|
||||
|
||||
struct poly1305_desc_ctx {
|
||||
/* partial buffer */
|
||||
u8 buf[POLY1305_BLOCK_SIZE];
|
||||
|
@ -45,12 +55,15 @@ struct poly1305_desc_ctx {
|
|||
unsigned int buflen;
|
||||
/* finalize key */
|
||||
u32 s[4];
|
||||
/* accumulator */
|
||||
struct poly1305_state h;
|
||||
/* key */
|
||||
union {
|
||||
struct poly1305_key opaque_r[CONFIG_CRYPTO_LIB_POLY1305_RSIZE];
|
||||
struct poly1305_core_key core_r;
|
||||
struct {
|
||||
struct poly1305_state h;
|
||||
union {
|
||||
struct poly1305_key opaque_r[CONFIG_CRYPTO_LIB_POLY1305_RSIZE];
|
||||
struct poly1305_core_key core_r;
|
||||
};
|
||||
};
|
||||
struct poly1305_block_state state;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -7,54 +7,45 @@
|
|||
* Based on public domain code by Andrew Moon and Daniel J. Bernstein.
|
||||
*/
|
||||
|
||||
#include <crypto/internal/blockhash.h>
|
||||
#include <crypto/internal/poly1305.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
void poly1305_block_init_generic(struct poly1305_block_state *desc,
|
||||
const u8 raw_key[POLY1305_BLOCK_SIZE])
|
||||
{
|
||||
poly1305_core_init(&desc->h);
|
||||
poly1305_core_setkey(&desc->core_r, raw_key);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(poly1305_block_init_generic);
|
||||
|
||||
void poly1305_init_generic(struct poly1305_desc_ctx *desc,
|
||||
const u8 key[POLY1305_KEY_SIZE])
|
||||
{
|
||||
poly1305_core_setkey(&desc->core_r, key);
|
||||
desc->s[0] = get_unaligned_le32(key + 16);
|
||||
desc->s[1] = get_unaligned_le32(key + 20);
|
||||
desc->s[2] = get_unaligned_le32(key + 24);
|
||||
desc->s[3] = get_unaligned_le32(key + 28);
|
||||
poly1305_core_init(&desc->h);
|
||||
desc->buflen = 0;
|
||||
poly1305_block_init_generic(&desc->state, key);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(poly1305_init_generic);
|
||||
|
||||
static inline void poly1305_blocks(struct poly1305_block_state *state,
|
||||
const u8 *src, unsigned int len)
|
||||
{
|
||||
poly1305_blocks_generic(state, src, len, 1);
|
||||
}
|
||||
|
||||
void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
unsigned int bytes;
|
||||
|
||||
if (unlikely(desc->buflen)) {
|
||||
bytes = min(nbytes, POLY1305_BLOCK_SIZE - desc->buflen);
|
||||
memcpy(desc->buf + desc->buflen, src, bytes);
|
||||
src += bytes;
|
||||
nbytes -= bytes;
|
||||
desc->buflen += bytes;
|
||||
|
||||
if (desc->buflen == POLY1305_BLOCK_SIZE) {
|
||||
poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf,
|
||||
1, 1);
|
||||
desc->buflen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(nbytes >= POLY1305_BLOCK_SIZE)) {
|
||||
poly1305_core_blocks(&desc->h, &desc->core_r, src,
|
||||
nbytes / POLY1305_BLOCK_SIZE, 1);
|
||||
src += nbytes - (nbytes % POLY1305_BLOCK_SIZE);
|
||||
nbytes %= POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (unlikely(nbytes)) {
|
||||
desc->buflen = nbytes;
|
||||
memcpy(desc->buf, src, nbytes);
|
||||
}
|
||||
desc->buflen = BLOCK_HASH_UPDATE(poly1305_blocks, &desc->state,
|
||||
src, nbytes, POLY1305_BLOCK_SIZE,
|
||||
desc->buf, desc->buflen);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(poly1305_update_generic);
|
||||
|
||||
|
@ -64,10 +55,11 @@ void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *dst)
|
|||
desc->buf[desc->buflen++] = 1;
|
||||
memset(desc->buf + desc->buflen, 0,
|
||||
POLY1305_BLOCK_SIZE - desc->buflen);
|
||||
poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf, 1, 0);
|
||||
poly1305_blocks_generic(&desc->state, desc->buf,
|
||||
POLY1305_BLOCK_SIZE, 0);
|
||||
}
|
||||
|
||||
poly1305_core_emit(&desc->h, desc->s, dst);
|
||||
poly1305_emit_generic(&desc->h, dst, desc->s);
|
||||
*desc = (struct poly1305_desc_ctx){};
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(poly1305_final_generic);
|
||||
|
|
Loading…
Add table
Reference in a new issue