xref: /freebsd/sys/crypto/blake2/blake2-sw.c (revision 123af6ec70016f5556da5972d4d63c7d175c06d3)
1 /* This file is in the public domain. */
2 
3 #include <sys/cdefs.h>
4 __FBSDID("$FreeBSD$");
5 
6 #include <contrib/libb2/blake2.h>
7 #include <opencrypto/xform_auth.h>
8 
9 extern int blake2b_init_ref(blake2b_state *S, size_t outlen);
10 extern int blake2b_init_param_ref(blake2b_state *S, const blake2b_param *P);
11 extern int blake2b_init_key_ref(blake2b_state *S, size_t outlen,
12     const void *key, size_t keylen);
13 extern int blake2b_update_ref(blake2b_state *S, const uint8_t *in,
14     size_t inlen);
15 extern int blake2b_final_ref(blake2b_state *S, uint8_t *out, size_t outlen);
16 extern int blake2b_ref(uint8_t *out, const void *in, const void *key,
17     size_t outlen, size_t inlen, size_t keylen);
18 
19 extern int blake2s_init_ref(blake2s_state *S, size_t outlen);
20 extern int blake2s_init_param_ref(blake2s_state *S, const blake2s_param *P);
21 extern int blake2s_init_key_ref(blake2s_state *S, size_t outlen,
22     const void *key, size_t keylen);
23 extern int blake2s_update_ref(blake2s_state *S, const uint8_t *in,
24     size_t inlen);
25 extern int blake2s_final_ref(blake2s_state *S, uint8_t *out, size_t outlen);
26 extern int blake2s_ref(uint8_t *out, const void *in, const void *key,
27     size_t outlen, size_t inlen, size_t keylen);
28 
29 struct blake2b_xform_ctx {
30 	blake2b_state state;
31 	uint8_t key[BLAKE2B_KEYBYTES];
32 	uint16_t klen;
33 };
34 CTASSERT(sizeof(union authctx) >= sizeof(struct blake2b_xform_ctx));
35 
36 static void
37 blake2b_xform_init(void *vctx)
38 {
39 	struct blake2b_xform_ctx *ctx = vctx;
40 	int rc;
41 
42 	if (ctx->klen > 0)
43 		rc = blake2b_init_key_ref(&ctx->state, BLAKE2B_OUTBYTES,
44 		    ctx->key, ctx->klen);
45 	else
46 		rc = blake2b_init_ref(&ctx->state, BLAKE2B_OUTBYTES);
47 	if (rc != 0)
48 		panic("blake2b_init_key: invalid arguments");
49 }
50 
51 static void
52 blake2b_xform_setkey(void *vctx, const uint8_t *key, uint16_t klen)
53 {
54 	struct blake2b_xform_ctx *ctx = vctx;
55 
56 	if (klen > sizeof(ctx->key))
57 		panic("invalid klen %u", (unsigned)klen);
58 	memcpy(ctx->key, key, klen);
59 	ctx->klen = klen;
60 }
61 
62 static int
63 blake2b_xform_update(void *vctx, const uint8_t *data, uint16_t len)
64 {
65 	struct blake2b_xform_ctx *ctx = vctx;
66 	int rc;
67 
68 	rc = blake2b_update_ref(&ctx->state, data, len);
69 	if (rc != 0)
70 		return (EINVAL);
71 	return (0);
72 }
73 
74 static void
75 blake2b_xform_final(uint8_t *out, void *vctx)
76 {
77 	struct blake2b_xform_ctx *ctx = vctx;
78 	int rc;
79 
80 	rc = blake2b_final_ref(&ctx->state, out, BLAKE2B_OUTBYTES);
81 	if (rc != 0)
82 		panic("blake2b_final: invalid");
83 }
84 
85 struct auth_hash auth_hash_blake2b = {
86 	.type = CRYPTO_BLAKE2B,
87 	.name = "Blake2b",
88 	.keysize = BLAKE2B_KEYBYTES,
89 	.hashsize = BLAKE2B_OUTBYTES,
90 	.ctxsize = sizeof(struct blake2b_xform_ctx),
91 	.Setkey = blake2b_xform_setkey,
92 	.Init = blake2b_xform_init,
93 	.Update = blake2b_xform_update,
94 	.Final = blake2b_xform_final,
95 };
96 
97 struct blake2s_xform_ctx {
98 	blake2s_state state;
99 	uint8_t key[BLAKE2S_KEYBYTES];
100 	uint16_t klen;
101 };
102 CTASSERT(sizeof(union authctx) >= sizeof(struct blake2s_xform_ctx));
103 
104 static void
105 blake2s_xform_init(void *vctx)
106 {
107 	struct blake2s_xform_ctx *ctx = vctx;
108 	int rc;
109 
110 	if (ctx->klen > 0)
111 		rc = blake2s_init_key_ref(&ctx->state, BLAKE2S_OUTBYTES,
112 		    ctx->key, ctx->klen);
113 	else
114 		rc = blake2s_init_ref(&ctx->state, BLAKE2S_OUTBYTES);
115 	if (rc != 0)
116 		panic("blake2s_init_key: invalid arguments");
117 }
118 
119 static void
120 blake2s_xform_setkey(void *vctx, const uint8_t *key, uint16_t klen)
121 {
122 	struct blake2s_xform_ctx *ctx = vctx;
123 
124 	if (klen > sizeof(ctx->key))
125 		panic("invalid klen %u", (unsigned)klen);
126 	memcpy(ctx->key, key, klen);
127 	ctx->klen = klen;
128 }
129 
130 static int
131 blake2s_xform_update(void *vctx, const uint8_t *data, uint16_t len)
132 {
133 	struct blake2s_xform_ctx *ctx = vctx;
134 	int rc;
135 
136 	rc = blake2s_update_ref(&ctx->state, data, len);
137 	if (rc != 0)
138 		return (EINVAL);
139 	return (0);
140 }
141 
142 static void
143 blake2s_xform_final(uint8_t *out, void *vctx)
144 {
145 	struct blake2s_xform_ctx *ctx = vctx;
146 	int rc;
147 
148 	rc = blake2s_final_ref(&ctx->state, out, BLAKE2S_OUTBYTES);
149 	if (rc != 0)
150 		panic("blake2s_final: invalid");
151 }
152 
153 struct auth_hash auth_hash_blake2s = {
154 	.type = CRYPTO_BLAKE2S,
155 	.name = "Blake2s",
156 	.keysize = BLAKE2S_KEYBYTES,
157 	.hashsize = BLAKE2S_OUTBYTES,
158 	.ctxsize = sizeof(struct blake2s_xform_ctx),
159 	.Setkey = blake2s_xform_setkey,
160 	.Init = blake2s_xform_init,
161 	.Update = blake2s_xform_update,
162 	.Final = blake2s_xform_final,
163 };
164