Line data Source code
1 : /*
2 : * Copyright (c) 2015 Mike Belopuhov
3 : *
4 : * Permission to use, copy, modify, and distribute this software for any
5 : * purpose with or without fee is hereby granted, provided that the above
6 : * copyright notice and this permission notice appear in all copies.
7 : *
8 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 : */
16 :
17 : #include <sys/param.h>
18 : #include <sys/systm.h>
19 :
20 : #include <crypto/chacha_private.h>
21 : #include <crypto/poly1305.h>
22 : #include <crypto/chachapoly.h>
23 :
24 : int
25 0 : chacha20_setkey(void *sched, u_int8_t *key, int len)
26 : {
27 0 : struct chacha20_ctx *ctx = (struct chacha20_ctx *)sched;
28 :
29 0 : if (len != CHACHA20_KEYSIZE + CHACHA20_SALT)
30 0 : return (-1);
31 :
32 : /* initial counter is 1 */
33 0 : ctx->nonce[0] = 1;
34 0 : memcpy(ctx->nonce + CHACHA20_CTR, key + CHACHA20_KEYSIZE,
35 : CHACHA20_SALT);
36 0 : chacha_keysetup((chacha_ctx *)&ctx->block, key, CHACHA20_KEYSIZE * 8);
37 0 : return (0);
38 0 : }
39 :
40 : void
41 0 : chacha20_reinit(caddr_t key, u_int8_t *iv)
42 : {
43 0 : struct chacha20_ctx *ctx = (struct chacha20_ctx *)key;
44 :
45 0 : chacha_ivsetup((chacha_ctx *)ctx->block, iv, ctx->nonce);
46 0 : }
47 :
48 : void
49 0 : chacha20_crypt(caddr_t key, u_int8_t *data)
50 : {
51 0 : struct chacha20_ctx *ctx = (struct chacha20_ctx *)key;
52 :
53 0 : chacha_encrypt_bytes((chacha_ctx *)ctx->block, data, data,
54 : CHACHA20_BLOCK_LEN);
55 0 : }
56 :
57 : void
58 0 : Chacha20_Poly1305_Init(void *xctx)
59 : {
60 0 : CHACHA20_POLY1305_CTX *ctx = xctx;
61 :
62 0 : memset(ctx, 0, sizeof(*ctx));
63 0 : }
64 :
65 : void
66 0 : Chacha20_Poly1305_Setkey(void *xctx, const uint8_t *key, uint16_t klen)
67 : {
68 0 : CHACHA20_POLY1305_CTX *ctx = xctx;
69 :
70 : /* salt is provided with the key material */
71 0 : memcpy(ctx->nonce + CHACHA20_CTR, key + CHACHA20_KEYSIZE,
72 : CHACHA20_SALT);
73 0 : chacha_keysetup((chacha_ctx *)&ctx->chacha, key, CHACHA20_KEYSIZE * 8);
74 0 : }
75 :
76 : void
77 0 : Chacha20_Poly1305_Reinit(void *xctx, const uint8_t *iv, uint16_t ivlen)
78 : {
79 0 : CHACHA20_POLY1305_CTX *ctx = xctx;
80 :
81 : /* initial counter is 0 */
82 0 : chacha_ivsetup((chacha_ctx *)&ctx->chacha, iv, ctx->nonce);
83 0 : chacha_encrypt_bytes((chacha_ctx *)&ctx->chacha, ctx->key, ctx->key,
84 : POLY1305_KEYLEN);
85 0 : poly1305_init((poly1305_state *)&ctx->poly, ctx->key);
86 0 : }
87 :
88 : int
89 0 : Chacha20_Poly1305_Update(void *xctx, const uint8_t *data, uint16_t len)
90 : {
91 : static const char zeroes[POLY1305_BLOCK_LEN];
92 0 : CHACHA20_POLY1305_CTX *ctx = xctx;
93 : size_t rem;
94 :
95 0 : poly1305_update((poly1305_state *)&ctx->poly, data, len);
96 :
97 : /* number of bytes in the last 16 byte block */
98 0 : rem = (len + POLY1305_BLOCK_LEN) & (POLY1305_BLOCK_LEN - 1);
99 0 : if (rem > 0)
100 0 : poly1305_update((poly1305_state *)&ctx->poly, zeroes,
101 0 : POLY1305_BLOCK_LEN - rem);
102 0 : return (0);
103 : }
104 :
105 : void
106 0 : Chacha20_Poly1305_Final(uint8_t tag[POLY1305_TAGLEN], void *xctx)
107 : {
108 0 : CHACHA20_POLY1305_CTX *ctx = xctx;
109 :
110 0 : poly1305_finish((poly1305_state *)&ctx->poly, tag);
111 0 : explicit_bzero(ctx, sizeof(*ctx));
112 0 : }
|