1*a01e9ee8Sriastradh /* $NetBSD: aes_ccm_mbuf.c,v 1.1 2020/07/25 22:15:55 riastradh Exp $ */
2*a01e9ee8Sriastradh
3*a01e9ee8Sriastradh /*-
4*a01e9ee8Sriastradh * Copyright (c) 2020 The NetBSD Foundation, Inc.
5*a01e9ee8Sriastradh * All rights reserved.
6*a01e9ee8Sriastradh *
7*a01e9ee8Sriastradh * Redistribution and use in source and binary forms, with or without
8*a01e9ee8Sriastradh * modification, are permitted provided that the following conditions
9*a01e9ee8Sriastradh * are met:
10*a01e9ee8Sriastradh * 1. Redistributions of source code must retain the above copyright
11*a01e9ee8Sriastradh * notice, this list of conditions and the following disclaimer.
12*a01e9ee8Sriastradh * 2. Redistributions in binary form must reproduce the above copyright
13*a01e9ee8Sriastradh * notice, this list of conditions and the following disclaimer in the
14*a01e9ee8Sriastradh * documentation and/or other materials provided with the distribution.
15*a01e9ee8Sriastradh *
16*a01e9ee8Sriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17*a01e9ee8Sriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18*a01e9ee8Sriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*a01e9ee8Sriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20*a01e9ee8Sriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*a01e9ee8Sriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*a01e9ee8Sriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*a01e9ee8Sriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*a01e9ee8Sriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*a01e9ee8Sriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*a01e9ee8Sriastradh * POSSIBILITY OF SUCH DAMAGE.
27*a01e9ee8Sriastradh */
28*a01e9ee8Sriastradh
29*a01e9ee8Sriastradh #include <sys/cdefs.h>
30*a01e9ee8Sriastradh __KERNEL_RCSID(1, "$NetBSD: aes_ccm_mbuf.c,v 1.1 2020/07/25 22:15:55 riastradh Exp $");
31*a01e9ee8Sriastradh
32*a01e9ee8Sriastradh #include <sys/types.h>
33*a01e9ee8Sriastradh
34*a01e9ee8Sriastradh #include <sys/mbuf.h>
35*a01e9ee8Sriastradh
36*a01e9ee8Sriastradh #include <lib/libkern/libkern.h>
37*a01e9ee8Sriastradh
38*a01e9ee8Sriastradh #include <crypto/aes/aes_ccm.h>
39*a01e9ee8Sriastradh #include <crypto/aes/aes_ccm_mbuf.h>
40*a01e9ee8Sriastradh
41*a01e9ee8Sriastradh void
aes_ccm_enc_mbuf(struct aes_ccm * C,struct mbuf * m,size_t off,size_t len,void * tag)42*a01e9ee8Sriastradh aes_ccm_enc_mbuf(struct aes_ccm *C, struct mbuf *m, size_t off, size_t len,
43*a01e9ee8Sriastradh void *tag)
44*a01e9ee8Sriastradh {
45*a01e9ee8Sriastradh uint8_t *p;
46*a01e9ee8Sriastradh size_t seglen;
47*a01e9ee8Sriastradh
48*a01e9ee8Sriastradh while (off >= m->m_len) {
49*a01e9ee8Sriastradh KASSERT(m->m_next);
50*a01e9ee8Sriastradh m = m->m_next;
51*a01e9ee8Sriastradh off -= m->m_len;
52*a01e9ee8Sriastradh }
53*a01e9ee8Sriastradh
54*a01e9ee8Sriastradh for (; len > 0; m = m->m_next, off = 0, len -= seglen) {
55*a01e9ee8Sriastradh KASSERT(m->m_len >= off);
56*a01e9ee8Sriastradh p = mtod(m, uint8_t *) + off;
57*a01e9ee8Sriastradh seglen = MIN(m->m_len - off, len);
58*a01e9ee8Sriastradh aes_ccm_enc(C, p, p, seglen);
59*a01e9ee8Sriastradh }
60*a01e9ee8Sriastradh
61*a01e9ee8Sriastradh aes_ccm_tag(C, tag);
62*a01e9ee8Sriastradh }
63*a01e9ee8Sriastradh
64*a01e9ee8Sriastradh int
aes_ccm_dec_mbuf(struct aes_ccm * C,struct mbuf * m0,size_t off0,size_t len0,const void * tag)65*a01e9ee8Sriastradh aes_ccm_dec_mbuf(struct aes_ccm *C, struct mbuf *m0, size_t off0, size_t len0,
66*a01e9ee8Sriastradh const void *tag)
67*a01e9ee8Sriastradh {
68*a01e9ee8Sriastradh struct mbuf *m;
69*a01e9ee8Sriastradh size_t off, len;
70*a01e9ee8Sriastradh uint8_t *p;
71*a01e9ee8Sriastradh size_t seglen;
72*a01e9ee8Sriastradh
73*a01e9ee8Sriastradh while (off0 >= m0->m_len) {
74*a01e9ee8Sriastradh KASSERT(m0->m_next);
75*a01e9ee8Sriastradh m0 = m0->m_next;
76*a01e9ee8Sriastradh off0 -= m0->m_len;
77*a01e9ee8Sriastradh }
78*a01e9ee8Sriastradh
79*a01e9ee8Sriastradh for (m = m0, off = off0, len = len0;
80*a01e9ee8Sriastradh len > 0;
81*a01e9ee8Sriastradh m = m->m_next, off = 0, len -= seglen) {
82*a01e9ee8Sriastradh KASSERT(m->m_len >= off);
83*a01e9ee8Sriastradh p = mtod(m, uint8_t *) + off;
84*a01e9ee8Sriastradh seglen = MIN(m->m_len - off, len);
85*a01e9ee8Sriastradh aes_ccm_dec(C, p, p, seglen);
86*a01e9ee8Sriastradh }
87*a01e9ee8Sriastradh
88*a01e9ee8Sriastradh if (aes_ccm_verify(C, tag))
89*a01e9ee8Sriastradh return 1;
90*a01e9ee8Sriastradh
91*a01e9ee8Sriastradh /*
92*a01e9ee8Sriastradh * Verification failed. Zero the mbuf so we don't accidentally
93*a01e9ee8Sriastradh * leak anything about it.
94*a01e9ee8Sriastradh */
95*a01e9ee8Sriastradh for (m = m0, off = off0, len = len0;
96*a01e9ee8Sriastradh len > 0;
97*a01e9ee8Sriastradh m = m->m_next, off = 0, len -= seglen) {
98*a01e9ee8Sriastradh KASSERT(m->m_len >= off);
99*a01e9ee8Sriastradh p = mtod(m, uint8_t *) + off;
100*a01e9ee8Sriastradh seglen = MIN(m->m_len - off, len);
101*a01e9ee8Sriastradh memset(p, 0, seglen);
102*a01e9ee8Sriastradh }
103*a01e9ee8Sriastradh
104*a01e9ee8Sriastradh return 0;
105*a01e9ee8Sriastradh }
106