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