projects/linux·blob master · refs

169 lines · 4.6 KiB

1/* SPDX-License-Identifier: GPL-2.0 OR MIT */
2/*
3 * Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
4 */
5
6#ifndef _CRYPTO_BLAKE2S_H
7#define _CRYPTO_BLAKE2S_H
8
9#include <linux/bug.h>
10#include <linux/kconfig.h>
11#include <linux/types.h>
12#include <linux/string.h>
13
14enum blake2s_lengths {
15 BLAKE2S_BLOCK_SIZE = 64,
16 BLAKE2S_HASH_SIZE = 32,
17 BLAKE2S_KEY_SIZE = 32,
18
19 BLAKE2S_128_HASH_SIZE = 16,
20 BLAKE2S_160_HASH_SIZE = 20,
21 BLAKE2S_224_HASH_SIZE = 28,
22 BLAKE2S_256_HASH_SIZE = 32,
23};
24
25/**
26 * struct blake2s_ctx - Context for hashing a message with BLAKE2s
27 * @h: compression function state
28 * @t: block counter
29 * @f: finalization indicator
30 * @buf: partial block buffer; 'buflen' bytes are valid
31 * @buflen: number of bytes buffered in @buf
32 * @outlen: length of output hash value in bytes, at most BLAKE2S_HASH_SIZE
33 */
34struct blake2s_ctx {
35 /* 'h', 't', and 'f' are used in assembly code, so keep them as-is. */
36 u32 h[8];
37 u32 t[2];
38 u32 f[2];
39 u8 buf[BLAKE2S_BLOCK_SIZE];
40 unsigned int buflen;
41 unsigned int outlen;
42};
43
44/**
45 * blake2s_zeroize_ctx() - Zeroize a blake2s_ctx structure
46 * @ctx: The blake2s_ctx to zeroize
47 */
48static inline void blake2s_zeroize_ctx(struct blake2s_ctx *ctx)
49{
50 memzero_explicit(ctx, sizeof(*ctx));
51}
52
53enum blake2s_iv {
54 BLAKE2S_IV0 = 0x6A09E667UL,
55 BLAKE2S_IV1 = 0xBB67AE85UL,
56 BLAKE2S_IV2 = 0x3C6EF372UL,
57 BLAKE2S_IV3 = 0xA54FF53AUL,
58 BLAKE2S_IV4 = 0x510E527FUL,
59 BLAKE2S_IV5 = 0x9B05688CUL,
60 BLAKE2S_IV6 = 0x1F83D9ABUL,
61 BLAKE2S_IV7 = 0x5BE0CD19UL,
62};
63
64static inline void __blake2s_init(struct blake2s_ctx *ctx, size_t outlen,
65 const void *key, size_t keylen)
66{
67 ctx->h[0] = BLAKE2S_IV0 ^ (0x01010000 | keylen << 8 | outlen);
68 ctx->h[1] = BLAKE2S_IV1;
69 ctx->h[2] = BLAKE2S_IV2;
70 ctx->h[3] = BLAKE2S_IV3;
71 ctx->h[4] = BLAKE2S_IV4;
72 ctx->h[5] = BLAKE2S_IV5;
73 ctx->h[6] = BLAKE2S_IV6;
74 ctx->h[7] = BLAKE2S_IV7;
75 ctx->t[0] = 0;
76 ctx->t[1] = 0;
77 ctx->f[0] = 0;
78 ctx->f[1] = 0;
79 ctx->buflen = 0;
80 ctx->outlen = outlen;
81 if (keylen) {
82 memcpy(ctx->buf, key, keylen);
83 memset(&ctx->buf[keylen], 0, BLAKE2S_BLOCK_SIZE - keylen);
84 ctx->buflen = BLAKE2S_BLOCK_SIZE;
85 }
86}
87
88/**
89 * blake2s_init() - Initialize a BLAKE2s context for a new message (unkeyed)
90 * @ctx: the context to initialize
91 * @outlen: length of output hash value in bytes, at most BLAKE2S_HASH_SIZE
92 *
93 * Context: Any context.
94 */
95static inline void blake2s_init(struct blake2s_ctx *ctx, size_t outlen)
96{
97 __blake2s_init(ctx, outlen, NULL, 0);
98}
99
100/**
101 * blake2s_init_key() - Initialize a BLAKE2s context for a new message (keyed)
102 * @ctx: the context to initialize
103 * @outlen: length of output hash value in bytes, at most BLAKE2S_HASH_SIZE
104 * @key: the key
105 * @keylen: the key length in bytes, at most BLAKE2S_KEY_SIZE
106 *
107 * Context: Any context.
108 */
109static inline void blake2s_init_key(struct blake2s_ctx *ctx, size_t outlen,
110 const void *key, size_t keylen)
111{
112 WARN_ON(IS_ENABLED(DEBUG) && (!outlen || outlen > BLAKE2S_HASH_SIZE ||
113 !key || !keylen || keylen > BLAKE2S_KEY_SIZE));
114
115 __blake2s_init(ctx, outlen, key, keylen);
116}
117
118/**
119 * blake2s_update() - Update a BLAKE2s context with message data
120 * @ctx: the context to update; must have been initialized
121 * @in: the message data
122 * @inlen: the data length in bytes
123 *
124 * This can be called any number of times.
125 *
126 * Context: Any context.
127 */
128void blake2s_update(struct blake2s_ctx *ctx, const u8 *in, size_t inlen);
129
130/**
131 * blake2s_final() - Finish computing a BLAKE2s hash
132 * @ctx: the context to finalize; must have been initialized
133 * @out: (output) the resulting BLAKE2s hash. Its length will be equal to the
134 * @outlen that was passed to blake2s_init() or blake2s_init_key().
135 *
136 * After finishing, this zeroizes @ctx. So the caller does not need to do it.
137 *
138 * Context: Any context.
139 */
140void blake2s_final(struct blake2s_ctx *ctx, u8 *out);
141
142/**
143 * blake2s() - Compute BLAKE2s hash in one shot
144 * @key: the key, or NULL for an unkeyed hash
145 * @keylen: the key length in bytes (at most BLAKE2S_KEY_SIZE), or 0 for an
146 * unkeyed hash
147 * @in: the message data
148 * @inlen: the data length in bytes
149 * @out: (output) the resulting BLAKE2s hash, with length @outlen
150 * @outlen: length of output hash value in bytes, at most BLAKE2S_HASH_SIZE
151 *
152 * Context: Any context.
153 */
154static inline void blake2s(const u8 *key, size_t keylen,
155 const u8 *in, size_t inlen,
156 u8 *out, size_t outlen)
157{
158 struct blake2s_ctx ctx;
159
160 WARN_ON(IS_ENABLED(DEBUG) && ((!in && inlen > 0) || !out || !outlen ||
161 outlen > BLAKE2S_HASH_SIZE || keylen > BLAKE2S_KEY_SIZE ||
162 (!key && keylen)));
163
164 __blake2s_init(&ctx, outlen, key, keylen);
165 blake2s_update(&ctx, in, inlen);
166 blake2s_final(&ctx, out);
167}
168
169#endif /* _CRYPTO_BLAKE2S_H */