1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29/*
30 * mdb dcmds for selected structures from
31 * usr/src/uts/common/sys/crypto/common.h
32 */
33
34#include <sys/mdb_modapi.h>
35#include <sys/modctl.h>
36#include <sys/types.h>
37#include <sys/crypto/api.h>
38#include <sys/crypto/common.h>
39#include <sys/crypto/spi.h>
40#include <sys/crypto/impl.h>
41#include "crypto_cmds.h"
42
43/*ARGSUSED*/
44int
45crypto_mechanism(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
46{
47	crypto_mechanism_t mch;
48
49	if (!(flags & DCMD_ADDRSPEC))
50		return (DCMD_USAGE);
51
52	if (mdb_vread(&mch, sizeof (crypto_mechanism_t), addr) == -1) {
53		mdb_warn("cannot read %p", addr);
54		return (DCMD_ERR);
55	}
56	/* XXX a future RFE will interpret cm_type */
57	mdb_printf("cm_type\t%ll#x\n", mch.cm_type);
58	mdb_printf("cm_param\t%p\n", mch.cm_param);
59	mdb_printf("cm_param_len\t%u\n", mch.cm_param_len);
60	return (DCMD_OK);
61}
62
63/*ARGSUSED*/
64static void
65iovec_prt(iovec_t *addr)
66{
67	mdb_printf("iov_base\t%p\n", addr->iov_base);
68	mdb_printf("iov_len\t\t%d\n", addr->iov_len);
69}
70
71/*ARGSUSED*/
72static void
73uio_prt(uio_t *addr)
74{
75	char *segstrings[] = {
76		"UIO_USERSPACE",
77		"UIO_SYSSPACE",
78		"UIO_USERISPACE"
79	};
80	iovec_t iov;
81	uio_t uio;
82	int i;
83
84	mdb_printf("uio\t%p\n", addr);
85	if (mdb_vread(&uio, sizeof (uio_t), (uintptr_t)addr)
86		== -1) {
87		mdb_warn("uio_prt: could not read uio");
88	}
89	mdb_inc_indent(4);
90	for (i = 0; i < uio.uio_iovcnt; i++) {
91		if (mdb_vread(&iov, sizeof (iovec_t),
92		    (uintptr_t)(uio.uio_iov +i))
93			== -1) {
94			mdb_printf("uio_iov\t?????");
95			mdb_warn("uio_prt: could not read uio_iov[%s]", i);
96		} else
97		    iovec_prt(&iov);
98	}
99	mdb_dec_indent(4);
100	mdb_printf("uio_iovcnt\t%d\n", uio.uio_iovcnt);
101	mdb_printf("uio_offset\t%lld\n", uio.uio_offset);
102	mdb_printf("uio_segflg\t%s", segstrings[uio.uio_segflg]);
103	mdb_printf("uio_fmode\t0%o", (int)uio.uio_fmode);
104	mdb_printf("uio_limit\t%lld", uio.uio_limit);
105	mdb_printf("uio_resid\t%ld", uio.uio_resid);
106}
107
108static char *cdstrings[] = {
109	"INVALID FORMAT",
110	"CRYPTO_DATA_RAW",
111	"CRYPTO_DATA_UIO",
112	"CRYPTO_DATA_MBLK"
113};
114
115/*
116 * Routine to print either of two structrually identical sub-structures --
117 * with different naming conventions.  Might be changed if we decide
118 * to merge the two.  They are the cdu union from crypto_data_t and
119 * the one from crypto_dual_data_t.
120 */
121
122typedef union crypto_data_union {
123	iovec_t	cdu_raw;		/* Raw format */
124	uio_t	*cdu_uio;		/* uio scatter-gather format */
125	mblk_t	*cdu_mp;		/* The mblk chain */
126} crypto_data_union_t;
127
128/*ARGSUSED*/
129static void
130prt_cdu(crypto_data_union_t *cdu, int format, const char *prefix)
131{
132
133	switch (format) {
134		case CRYPTO_DATA_RAW:
135		    mdb_printf("%s_raw:\n", prefix);
136		    mdb_inc_indent(4);
137		    iovec_prt(&cdu->cdu_raw);
138		    mdb_dec_indent(4);
139		    break;
140
141		case CRYPTO_DATA_UIO:
142		    mdb_printf("%s_uio:\n", prefix);
143		    mdb_inc_indent(4);
144		    uio_prt(cdu->cdu_uio);
145		    mdb_dec_indent(4);
146		    break;
147
148		case CRYPTO_DATA_MBLK:
149		    mdb_printf("%s_mp:\t\t%p\n", prefix, cdu->cdu_mp);
150		    break;
151
152		default:
153		    mdb_printf("cm_format\t??????\n");
154		    break;
155	}
156}
157
158/*ARGSUSED*/
159int
160crypto_data(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
161{
162	crypto_data_t data;
163
164	if (!(flags & DCMD_ADDRSPEC))
165		return (DCMD_USAGE);
166
167	if (mdb_vread(&data, sizeof (crypto_data_t), addr) == -1) {
168		mdb_warn("cannot read %p", addr);
169		return (DCMD_ERR);
170	}
171	if ((data.cd_format >= CRYPTO_DATA_RAW) &&
172	    (data.cd_format <= CRYPTO_DATA_MBLK))
173		mdb_printf("cm_format\t%s\n", cdstrings[data.cd_format]);
174	else
175		mdb_printf("bad cm_format\t%d\n", data.cd_format);
176	mdb_printf("cm_offset\t%ld\n", data.cd_offset);
177	mdb_printf("cm_length\t%ld\n", data.cd_length);
178	mdb_printf("cm_miscdata\t%p\n", data.cd_miscdata);
179	mdb_inc_indent(4);
180	prt_cdu((crypto_data_union_t *)&data.cdu, data.cd_format, "cdu");
181	mdb_dec_indent(4);
182	return (DCMD_OK);
183}
184
185/*ARGSUSED*/
186int
187crypto_dual_data(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
188{
189	crypto_dual_data_t ddata;
190
191	if (!(flags & DCMD_ADDRSPEC))
192		return (DCMD_USAGE);
193
194	if (mdb_vread(&ddata, sizeof (crypto_dual_data_t), addr) == -1) {
195		mdb_warn("cannot read %p", addr);
196		return (DCMD_ERR);
197	}
198	if ((ddata.dd_format > CRYPTO_DATA_RAW) &&
199	    (ddata.dd_format <= CRYPTO_DATA_MBLK))
200		mdb_printf("dd_format\t%s\n", cdstrings[ddata.dd_format]);
201	else
202		mdb_printf("bad dd_format\t%d\n", ddata.dd_format);
203	mdb_printf("dd_offset1\t%ld\n", ddata.dd_offset1);
204	mdb_printf("dd_len1\t%ld\n", ddata.dd_len1);
205	mdb_printf("dd_offset2\t%ld\n", ddata.dd_offset2);
206	mdb_printf("dd_len2\t%ld\n", ddata.dd_len2);
207	mdb_printf("dd_miscdata\t%p\n", ddata.dd_miscdata);
208	mdb_printf("cdu:\n");
209	mdb_inc_indent(4);
210	prt_cdu((crypto_data_union_t *)&ddata.dd_data.cdu, ddata.dd_format,
211	    "ddu");
212	mdb_dec_indent(4);
213	return (DCMD_OK);
214}
215
216
217/*ARGSUSED*/
218int
219crypto_key(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
220{
221	crypto_key_t key;
222
223	if (!(flags & DCMD_ADDRSPEC))
224		return (DCMD_USAGE);
225
226	if (mdb_vread(&key, sizeof (crypto_key_t), addr) == -1) {
227		mdb_warn("cannot read %p", addr);
228		return (DCMD_ERR);
229	}
230	switch (key.ck_format) {
231		case CRYPTO_KEY_RAW:
232		    mdb_printf("ck_format:\tCRYPTO_KEY_RAW\n");
233		    mdb_printf(
234			"cku_data.cku_key_value.cku_data.cku_v_length:\t%d\n",
235			    key.cku_data.cku_key_value.cku_v_length);
236		    mdb_printf("cku_data.cku_key_value.cku_v_data:\t%p\n",
237			key.cku_data.cku_key_value.cku_v_data);
238		    break;
239		case CRYPTO_KEY_REFERENCE:
240		    mdb_printf("ck_format:\tCRYPTO_KEY_REFERENCE\n");
241		    mdb_printf("cku_data.cku_key_id:\t%u\n",
242			key.cku_data.cku_key_id);
243		    break;
244		case CRYPTO_KEY_ATTR_LIST:
245			mdb_printf("ck_format:\tCRYPTO_KEY_ATTR_LIST\n");
246			mdb_printf("cku_data.cku_key_attrs.cku_a_count:\t%u\n",
247				key.cku_data.cku_key_attrs.cku_a_count);
248			mdb_printf("cku_data.cku_key_attrs.cku_o_oattr:\t%p\n",
249				key.cku_data.cku_key_attrs.cku_a_oattr);
250			break;
251		default:
252			mdb_printf("ck_format:\t\t?????\n");
253			break;
254	}
255	return (DCMD_OK);
256}
257