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