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