xref: /netbsd-src/sys/crypto/aes/aes_ccm_mbuf.c (revision a01e9ee8031f0342a7a9ce9ebca8551d5192a3f2)
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