1 /*
2 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3 * Copyright (c) 2017-2021 The strace developers.
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8
9 #include "defs.h"
10
11 #include "netlink.h"
12 #include "nlattr.h"
13
14 #include <linux/cryptouser.h>
15
16 #include "xlat/crypto_nl_attrs.h"
17
18
19 static bool
20 decode_crypto_report_generic(struct tcb *const tcp,
21 const kernel_ulong_t addr,
22 const unsigned int len,
23 const void *const opaque_data)
24 {
25 tprint_struct_begin();
26 tprints_field_name("type");
27 printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
28 tprint_struct_end();
29
30 return true;
31 }
32
33 static bool
34 decode_crypto_report_hash(struct tcb *const tcp,
35 const kernel_ulong_t addr,
36 const unsigned int len,
37 const void *const opaque_data)
38 {
39 struct crypto_report_hash rhash;
40
41 if (len < sizeof(rhash))
42 printstrn(tcp, addr, len);
43 else if (!umove_or_printaddr(tcp, addr, &rhash)) {
44 tprint_struct_begin();
45 PRINT_FIELD_CSTRING(rhash, type);
46 tprint_struct_next();
47 PRINT_FIELD_U(rhash, blocksize);
48 tprint_struct_next();
49 PRINT_FIELD_U(rhash, digestsize);
50 tprint_struct_end();
51 }
52
53 return true;
54 }
55
56 static bool
57 decode_crypto_report_blkcipher(struct tcb *const tcp,
58 const kernel_ulong_t addr,
59 const unsigned int len,
60 const void *const opaque_data)
61 {
62 struct crypto_report_blkcipher rblkcipher;
63
64 if (len < sizeof(rblkcipher))
65 printstrn(tcp, addr, len);
66 else if (!umove_or_printaddr(tcp, addr, &rblkcipher)) {
67 tprint_struct_begin();
68 PRINT_FIELD_CSTRING(rblkcipher, type);
69 tprint_struct_next();
70 PRINT_FIELD_CSTRING(rblkcipher, geniv);
71 tprint_struct_next();
72 PRINT_FIELD_U(rblkcipher, blocksize);
73 tprint_struct_next();
74 PRINT_FIELD_U(rblkcipher, min_keysize);
75 tprint_struct_next();
76 PRINT_FIELD_U(rblkcipher, max_keysize);
77 tprint_struct_next();
78 PRINT_FIELD_U(rblkcipher, ivsize);
79 tprint_struct_end();
80 }
81
82 return true;
83 }
84
85 static bool
86 decode_crypto_report_aead(struct tcb *const tcp,
87 const kernel_ulong_t addr,
88 const unsigned int len,
89 const void *const opaque_data)
90 {
91 struct crypto_report_aead raead;
92
93 if (len < sizeof(raead))
94 printstrn(tcp, addr, len);
95 else if (!umove_or_printaddr(tcp, addr, &raead)) {
96 tprint_struct_begin();
97 PRINT_FIELD_CSTRING(raead, type);
98 tprint_struct_next();
99 PRINT_FIELD_CSTRING(raead, geniv);
100 tprint_struct_next();
101 PRINT_FIELD_U(raead, blocksize);
102 tprint_struct_next();
103 PRINT_FIELD_U(raead, maxauthsize);
104 tprint_struct_next();
105 PRINT_FIELD_U(raead, ivsize);
106 tprint_struct_end();
107 }
108
109 return true;
110 }
111
112 static bool
113 decode_crypto_report_rng(struct tcb *const tcp,
114 const kernel_ulong_t addr,
115 const unsigned int len,
116 const void *const opaque_data)
117 {
118 struct crypto_report_rng rrng;
119
120 if (len < sizeof(rrng))
121 printstrn(tcp, addr, len);
122 else if (!umove_or_printaddr(tcp, addr, &rrng)) {
123 tprint_struct_begin();
124 PRINT_FIELD_CSTRING(rrng, type);
125 tprint_struct_next();
126 PRINT_FIELD_U(rrng, seedsize);
127 tprint_struct_end();
128 }
129
130 return true;
131 }
132
133 static bool
134 decode_crypto_report_cipher(struct tcb *const tcp,
135 const kernel_ulong_t addr,
136 const unsigned int len,
137 const void *const opaque_data)
138 {
139 struct crypto_report_cipher rcipher;
140
141 if (len < sizeof(rcipher))
142 printstrn(tcp, addr, len);
143 else if (!umove_or_printaddr(tcp, addr, &rcipher)) {
144 tprint_struct_begin();
145 PRINT_FIELD_CSTRING(rcipher, type);
146 tprint_struct_next();
147 PRINT_FIELD_U(rcipher, blocksize);
148 tprint_struct_next();
149 PRINT_FIELD_U(rcipher, min_keysize);
150 tprint_struct_next();
151 PRINT_FIELD_U(rcipher, max_keysize);
152 tprint_struct_end();
153 }
154
155 return true;
156 }
157
158 static const nla_decoder_t crypto_user_alg_nla_decoders[] = {
159 [CRYPTOCFGA_PRIORITY_VAL] = decode_nla_u32,
160 [CRYPTOCFGA_REPORT_LARVAL] = decode_crypto_report_generic,
161 [CRYPTOCFGA_REPORT_HASH] = decode_crypto_report_hash,
162 [CRYPTOCFGA_REPORT_BLKCIPHER] = decode_crypto_report_blkcipher,
163 [CRYPTOCFGA_REPORT_AEAD] = decode_crypto_report_aead,
164 [CRYPTOCFGA_REPORT_COMPRESS] = decode_crypto_report_generic,
165 [CRYPTOCFGA_REPORT_RNG] = decode_crypto_report_rng,
166 [CRYPTOCFGA_REPORT_CIPHER] = decode_crypto_report_cipher,
167 [CRYPTOCFGA_REPORT_AKCIPHER] = decode_crypto_report_generic,
168 [CRYPTOCFGA_REPORT_KPP] = decode_crypto_report_generic,
169 [CRYPTOCFGA_REPORT_ACOMP] = decode_crypto_report_generic
170 };
171
172 static void
173 decode_crypto_user_alg(struct tcb *const tcp,
174 const kernel_ulong_t addr,
175 const unsigned int len)
176 {
177 struct crypto_user_alg alg;
178
179 if (len < sizeof(alg))
180 printstrn(tcp, addr, len);
181 else if (!umove_or_printaddr(tcp, addr, &alg)) {
182 tprint_struct_begin();
183 PRINT_FIELD_CSTRING(alg, cru_name);
184 tprint_struct_next();
185 PRINT_FIELD_CSTRING(alg, cru_driver_name);
186 tprint_struct_next();
187 PRINT_FIELD_CSTRING(alg, cru_module_name);
188 tprint_struct_next();
189 PRINT_FIELD_X(alg, cru_type);
190 tprint_struct_next();
191 PRINT_FIELD_X(alg, cru_mask);
192 tprint_struct_next();
193 PRINT_FIELD_U(alg, cru_refcnt);
194 tprint_struct_next();
195 PRINT_FIELD_X(alg, cru_flags);
196 tprint_struct_end();
197
198 const size_t offset = NLMSG_ALIGN(sizeof(alg));
199 if (len > offset) {
200 tprint_array_next();
201 decode_nlattr(tcp, addr + offset, len - offset,
202 crypto_nl_attrs, "CRYPTOCFGA_???",
203 crypto_user_alg_nla_decoders,
204 ARRAY_SIZE(crypto_user_alg_nla_decoders),
205 NULL);
206 }
207 }
208 }
209
210 bool
211 decode_netlink_crypto(struct tcb *const tcp,
212 const struct nlmsghdr *const nlmsghdr,
213 const kernel_ulong_t addr,
214 const unsigned int len)
215 {
216 switch (nlmsghdr->nlmsg_type) {
217 case CRYPTO_MSG_NEWALG:
218 case CRYPTO_MSG_DELALG:
219 case CRYPTO_MSG_UPDATEALG:
220 case CRYPTO_MSG_GETALG:
221 decode_crypto_user_alg(tcp, addr, len);
222 break;
223 default:
224 return false;
225 }
226
227 return true;
228 }