cgd.c revision 1.116 1 /* $NetBSD: cgd.c,v 1.116 2018/01/23 22:42:29 pgoyette Exp $ */
2
3 /*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Roland C. Dowdeswell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.116 2018/01/23 22:42:29 pgoyette Exp $");
34
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/proc.h>
39 #include <sys/errno.h>
40 #include <sys/buf.h>
41 #include <sys/bufq.h>
42 #include <sys/malloc.h>
43 #include <sys/module.h>
44 #include <sys/pool.h>
45 #include <sys/ioctl.h>
46 #include <sys/device.h>
47 #include <sys/disk.h>
48 #include <sys/disklabel.h>
49 #include <sys/fcntl.h>
50 #include <sys/namei.h> /* for pathbuf */
51 #include <sys/vnode.h>
52 #include <sys/conf.h>
53 #include <sys/syslog.h>
54
55 #include <dev/dkvar.h>
56 #include <dev/cgdvar.h>
57
58 #include <miscfs/specfs/specdev.h> /* for v_rdev */
59
60 #include "ioconf.h"
61
62 struct selftest_params {
63 const char *alg;
64 int blocksize; /* number of bytes */
65 int secsize;
66 daddr_t blkno;
67 int keylen; /* number of bits */
68 int txtlen; /* number of bytes */
69 const uint8_t *key;
70 const uint8_t *ptxt;
71 const uint8_t *ctxt;
72 };
73
74 /* Entry Point Functions */
75
76 static dev_type_open(cgdopen);
77 static dev_type_close(cgdclose);
78 static dev_type_read(cgdread);
79 static dev_type_write(cgdwrite);
80 static dev_type_ioctl(cgdioctl);
81 static dev_type_strategy(cgdstrategy);
82 static dev_type_dump(cgddump);
83 static dev_type_size(cgdsize);
84
85 const struct bdevsw cgd_bdevsw = {
86 .d_open = cgdopen,
87 .d_close = cgdclose,
88 .d_strategy = cgdstrategy,
89 .d_ioctl = cgdioctl,
90 .d_dump = cgddump,
91 .d_psize = cgdsize,
92 .d_discard = nodiscard,
93 .d_flag = D_DISK
94 };
95
96 const struct cdevsw cgd_cdevsw = {
97 .d_open = cgdopen,
98 .d_close = cgdclose,
99 .d_read = cgdread,
100 .d_write = cgdwrite,
101 .d_ioctl = cgdioctl,
102 .d_stop = nostop,
103 .d_tty = notty,
104 .d_poll = nopoll,
105 .d_mmap = nommap,
106 .d_kqfilter = nokqfilter,
107 .d_discard = nodiscard,
108 .d_flag = D_DISK
109 };
110
111 /*
112 * Vector 5 from IEEE 1619/D16 truncated to 64 bytes, blkno 1.
113 */
114 static const uint8_t selftest_aes_xts_256_ptxt[64] = {
115 0x27, 0xa7, 0x47, 0x9b, 0xef, 0xa1, 0xd4, 0x76,
116 0x48, 0x9f, 0x30, 0x8c, 0xd4, 0xcf, 0xa6, 0xe2,
117 0xa9, 0x6e, 0x4b, 0xbe, 0x32, 0x08, 0xff, 0x25,
118 0x28, 0x7d, 0xd3, 0x81, 0x96, 0x16, 0xe8, 0x9c,
119 0xc7, 0x8c, 0xf7, 0xf5, 0xe5, 0x43, 0x44, 0x5f,
120 0x83, 0x33, 0xd8, 0xfa, 0x7f, 0x56, 0x00, 0x00,
121 0x05, 0x27, 0x9f, 0xa5, 0xd8, 0xb5, 0xe4, 0xad,
122 0x40, 0xe7, 0x36, 0xdd, 0xb4, 0xd3, 0x54, 0x12,
123 };
124
125 static const uint8_t selftest_aes_xts_256_ctxt[512] = {
126 0x26, 0x4d, 0x3c, 0xa8, 0x51, 0x21, 0x94, 0xfe,
127 0xc3, 0x12, 0xc8, 0xc9, 0x89, 0x1f, 0x27, 0x9f,
128 0xef, 0xdd, 0x60, 0x8d, 0x0c, 0x02, 0x7b, 0x60,
129 0x48, 0x3a, 0x3f, 0xa8, 0x11, 0xd6, 0x5e, 0xe5,
130 0x9d, 0x52, 0xd9, 0xe4, 0x0e, 0xc5, 0x67, 0x2d,
131 0x81, 0x53, 0x2b, 0x38, 0xb6, 0xb0, 0x89, 0xce,
132 0x95, 0x1f, 0x0f, 0x9c, 0x35, 0x59, 0x0b, 0x8b,
133 0x97, 0x8d, 0x17, 0x52, 0x13, 0xf3, 0x29, 0xbb,
134 };
135
136 static const uint8_t selftest_aes_xts_256_key[33] = {
137 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45,
138 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26,
139 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93,
140 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95,
141 0
142 };
143
144 /*
145 * Vector 11 from IEEE 1619/D16 truncated to 64 bytes, blkno 0xffff.
146 */
147 static const uint8_t selftest_aes_xts_512_ptxt[64] = {
148 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
149 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
150 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
151 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
152 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
153 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
154 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
155 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
156 };
157
158 static const uint8_t selftest_aes_xts_512_ctxt[64] = {
159 0x77, 0xa3, 0x12, 0x51, 0x61, 0x8a, 0x15, 0xe6,
160 0xb9, 0x2d, 0x1d, 0x66, 0xdf, 0xfe, 0x7b, 0x50,
161 0xb5, 0x0b, 0xad, 0x55, 0x23, 0x05, 0xba, 0x02,
162 0x17, 0xa6, 0x10, 0x68, 0x8e, 0xff, 0x7e, 0x11,
163 0xe1, 0xd0, 0x22, 0x54, 0x38, 0xe0, 0x93, 0x24,
164 0x2d, 0x6d, 0xb2, 0x74, 0xfd, 0xe8, 0x01, 0xd4,
165 0xca, 0xe0, 0x6f, 0x20, 0x92, 0xc7, 0x28, 0xb2,
166 0x47, 0x85, 0x59, 0xdf, 0x58, 0xe8, 0x37, 0xc2,
167 };
168
169 static const uint8_t selftest_aes_xts_512_key[65] = {
170 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45,
171 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26,
172 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69,
173 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27,
174 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93,
175 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95,
176 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37,
177 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92,
178 0
179 };
180
181 const struct selftest_params selftests[] = {
182 {
183 .alg = "aes-xts",
184 .blocksize = 16,
185 .secsize = 512,
186 .blkno = 1,
187 .keylen = 256,
188 .txtlen = sizeof(selftest_aes_xts_256_ptxt),
189 .key = selftest_aes_xts_256_key,
190 .ptxt = selftest_aes_xts_256_ptxt,
191 .ctxt = selftest_aes_xts_256_ctxt
192 },
193 {
194 .alg = "aes-xts",
195 .blocksize = 16,
196 .secsize = 512,
197 .blkno = 0xffff,
198 .keylen = 512,
199 .txtlen = sizeof(selftest_aes_xts_512_ptxt),
200 .key = selftest_aes_xts_512_key,
201 .ptxt = selftest_aes_xts_512_ptxt,
202 .ctxt = selftest_aes_xts_512_ctxt
203 }
204 };
205
206 static int cgd_match(device_t, cfdata_t, void *);
207 static void cgd_attach(device_t, device_t, void *);
208 static int cgd_detach(device_t, int);
209 static struct cgd_softc *cgd_spawn(int);
210 static int cgd_destroy(device_t);
211
212 /* Internal Functions */
213
214 static int cgd_diskstart(device_t, struct buf *);
215 static void cgdiodone(struct buf *);
216 static int cgd_dumpblocks(device_t, void *, daddr_t, int);
217
218 static int cgd_ioctl_set(struct cgd_softc *, void *, struct lwp *);
219 static int cgd_ioctl_clr(struct cgd_softc *, struct lwp *);
220 static int cgd_ioctl_get(dev_t, void *, struct lwp *);
221 static int cgdinit(struct cgd_softc *, const char *, struct vnode *,
222 struct lwp *);
223 static void cgd_cipher(struct cgd_softc *, void *, void *,
224 size_t, daddr_t, size_t, int);
225
226 static struct dkdriver cgddkdriver = {
227 .d_minphys = minphys,
228 .d_open = cgdopen,
229 .d_close = cgdclose,
230 .d_strategy = cgdstrategy,
231 .d_iosize = NULL,
232 .d_diskstart = cgd_diskstart,
233 .d_dumpblocks = cgd_dumpblocks,
234 .d_lastclose = NULL
235 };
236
237 CFATTACH_DECL3_NEW(cgd, sizeof(struct cgd_softc),
238 cgd_match, cgd_attach, cgd_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
239
240 /* DIAGNOSTIC and DEBUG definitions */
241
242 #if defined(CGDDEBUG) && !defined(DEBUG)
243 #define DEBUG
244 #endif
245
246 #ifdef DEBUG
247 int cgddebug = 0;
248
249 #define CGDB_FOLLOW 0x1
250 #define CGDB_IO 0x2
251 #define CGDB_CRYPTO 0x4
252
253 #define IFDEBUG(x,y) if (cgddebug & (x)) y
254 #define DPRINTF(x,y) IFDEBUG(x, printf y)
255 #define DPRINTF_FOLLOW(y) DPRINTF(CGDB_FOLLOW, y)
256
257 static void hexprint(const char *, void *, int);
258
259 #else
260 #define IFDEBUG(x,y)
261 #define DPRINTF(x,y)
262 #define DPRINTF_FOLLOW(y)
263 #endif
264
265 #ifdef DIAGNOSTIC
266 #define DIAGPANIC(x) panic x
267 #define DIAGCONDPANIC(x,y) if (x) panic y
268 #else
269 #define DIAGPANIC(x)
270 #define DIAGCONDPANIC(x,y)
271 #endif
272
273 /* Global variables */
274
275 /* Utility Functions */
276
277 #define CGDUNIT(x) DISKUNIT(x)
278 #define GETCGD_SOFTC(_cs, x) if (!((_cs) = getcgd_softc(x))) return ENXIO
279
280 /* The code */
281
282 static struct cgd_softc *
283 getcgd_softc(dev_t dev)
284 {
285 int unit = CGDUNIT(dev);
286 struct cgd_softc *sc;
287
288 DPRINTF_FOLLOW(("getcgd_softc(0x%"PRIx64"): unit = %d\n", dev, unit));
289
290 sc = device_lookup_private(&cgd_cd, unit);
291 if (sc == NULL)
292 sc = cgd_spawn(unit);
293 return sc;
294 }
295
296 static int
297 cgd_match(device_t self, cfdata_t cfdata, void *aux)
298 {
299
300 return 1;
301 }
302
303 static void
304 cgd_attach(device_t parent, device_t self, void *aux)
305 {
306 struct cgd_softc *sc = device_private(self);
307
308 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO);
309 dk_init(&sc->sc_dksc, self, DKTYPE_CGD);
310 disk_init(&sc->sc_dksc.sc_dkdev, sc->sc_dksc.sc_xname, &cgddkdriver);
311
312 if (!pmf_device_register(self, NULL, NULL))
313 aprint_error_dev(self,
314 "unable to register power management hooks\n");
315 }
316
317
318 static int
319 cgd_detach(device_t self, int flags)
320 {
321 int ret;
322 const int pmask = 1 << RAW_PART;
323 struct cgd_softc *sc = device_private(self);
324 struct dk_softc *dksc = &sc->sc_dksc;
325
326 if (DK_BUSY(dksc, pmask))
327 return EBUSY;
328
329 if (DK_ATTACHED(dksc) &&
330 (ret = cgd_ioctl_clr(sc, curlwp)) != 0)
331 return ret;
332
333 disk_destroy(&dksc->sc_dkdev);
334 mutex_destroy(&sc->sc_lock);
335
336 return 0;
337 }
338
339 void
340 cgdattach(int num)
341 {
342 int error;
343
344 error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
345 if (error != 0)
346 aprint_error("%s: unable to register cfattach\n",
347 cgd_cd.cd_name);
348 }
349
350 static struct cgd_softc *
351 cgd_spawn(int unit)
352 {
353 cfdata_t cf;
354
355 cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
356 cf->cf_name = cgd_cd.cd_name;
357 cf->cf_atname = cgd_cd.cd_name;
358 cf->cf_unit = unit;
359 cf->cf_fstate = FSTATE_STAR;
360
361 return device_private(config_attach_pseudo(cf));
362 }
363
364 static int
365 cgd_destroy(device_t dev)
366 {
367 int error;
368 cfdata_t cf;
369
370 cf = device_cfdata(dev);
371 error = config_detach(dev, DETACH_QUIET);
372 if (error)
373 return error;
374 free(cf, M_DEVBUF);
375 return 0;
376 }
377
378 static int
379 cgdopen(dev_t dev, int flags, int fmt, struct lwp *l)
380 {
381 struct cgd_softc *cs;
382
383 DPRINTF_FOLLOW(("cgdopen(0x%"PRIx64", %d)\n", dev, flags));
384 GETCGD_SOFTC(cs, dev);
385 return dk_open(&cs->sc_dksc, dev, flags, fmt, l);
386 }
387
388 static int
389 cgdclose(dev_t dev, int flags, int fmt, struct lwp *l)
390 {
391 int error;
392 struct cgd_softc *cs;
393 struct dk_softc *dksc;
394
395 DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags));
396 GETCGD_SOFTC(cs, dev);
397 dksc = &cs->sc_dksc;
398 if ((error = dk_close(dksc, dev, flags, fmt, l)) != 0)
399 return error;
400
401 if (!DK_ATTACHED(dksc)) {
402 if ((error = cgd_destroy(cs->sc_dksc.sc_dev)) != 0) {
403 aprint_error_dev(dksc->sc_dev,
404 "unable to detach instance\n");
405 return error;
406 }
407 }
408 return 0;
409 }
410
411 static void
412 cgdstrategy(struct buf *bp)
413 {
414 struct cgd_softc *cs;
415
416 DPRINTF_FOLLOW(("cgdstrategy(%p): b_bcount = %ld\n", bp,
417 (long)bp->b_bcount));
418
419 cs = getcgd_softc(bp->b_dev);
420 if (!cs) {
421 bp->b_error = ENXIO;
422 goto bail;
423 }
424
425 /*
426 * Reject unaligned writes.
427 */
428 if (((uintptr_t)bp->b_data & 3) != 0) {
429 bp->b_error = EINVAL;
430 goto bail;
431 }
432
433 dk_strategy(&cs->sc_dksc, bp);
434 return;
435
436 bail:
437 bp->b_resid = bp->b_bcount;
438 biodone(bp);
439 return;
440 }
441
442 static int
443 cgdsize(dev_t dev)
444 {
445 struct cgd_softc *cs = getcgd_softc(dev);
446
447 DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev));
448 if (!cs)
449 return -1;
450 return dk_size(&cs->sc_dksc, dev);
451 }
452
453 /*
454 * cgd_{get,put}data are functions that deal with getting a buffer
455 * for the new encrypted data. We have a buffer per device so that
456 * we can ensure that we can always have a transaction in flight.
457 * We use this buffer first so that we have one less piece of
458 * malloc'ed data at any given point.
459 */
460
461 static void *
462 cgd_getdata(struct dk_softc *dksc, unsigned long size)
463 {
464 struct cgd_softc *cs = (struct cgd_softc *)dksc;
465 void * data = NULL;
466
467 mutex_enter(&cs->sc_lock);
468 if (cs->sc_data_used == 0) {
469 cs->sc_data_used = 1;
470 data = cs->sc_data;
471 }
472 mutex_exit(&cs->sc_lock);
473
474 if (data)
475 return data;
476
477 return malloc(size, M_DEVBUF, M_NOWAIT);
478 }
479
480 static void
481 cgd_putdata(struct dk_softc *dksc, void *data)
482 {
483 struct cgd_softc *cs = (struct cgd_softc *)dksc;
484
485 if (data == cs->sc_data) {
486 mutex_enter(&cs->sc_lock);
487 cs->sc_data_used = 0;
488 mutex_exit(&cs->sc_lock);
489 } else {
490 free(data, M_DEVBUF);
491 }
492 }
493
494 static int
495 cgd_diskstart(device_t dev, struct buf *bp)
496 {
497 struct cgd_softc *cs = device_private(dev);
498 struct dk_softc *dksc = &cs->sc_dksc;
499 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
500 struct buf *nbp;
501 void * addr;
502 void * newaddr;
503 daddr_t bn;
504 struct vnode *vp;
505
506 DPRINTF_FOLLOW(("cgd_diskstart(%p, %p)\n", dksc, bp));
507
508 bn = bp->b_rawblkno;
509
510 /*
511 * We attempt to allocate all of our resources up front, so that
512 * we can fail quickly if they are unavailable.
513 */
514 nbp = getiobuf(cs->sc_tvn, false);
515 if (nbp == NULL)
516 return EAGAIN;
517
518 /*
519 * If we are writing, then we need to encrypt the outgoing
520 * block into a new block of memory.
521 */
522 newaddr = addr = bp->b_data;
523 if ((bp->b_flags & B_READ) == 0) {
524 newaddr = cgd_getdata(dksc, bp->b_bcount);
525 if (!newaddr) {
526 putiobuf(nbp);
527 return EAGAIN;
528 }
529 cgd_cipher(cs, newaddr, addr, bp->b_bcount, bn,
530 dg->dg_secsize, CGD_CIPHER_ENCRYPT);
531 }
532
533 nbp->b_data = newaddr;
534 nbp->b_flags = bp->b_flags;
535 nbp->b_oflags = bp->b_oflags;
536 nbp->b_cflags = bp->b_cflags;
537 nbp->b_iodone = cgdiodone;
538 nbp->b_proc = bp->b_proc;
539 nbp->b_blkno = btodb(bn * dg->dg_secsize);
540 nbp->b_bcount = bp->b_bcount;
541 nbp->b_private = bp;
542
543 BIO_COPYPRIO(nbp, bp);
544
545 if ((nbp->b_flags & B_READ) == 0) {
546 vp = nbp->b_vp;
547 mutex_enter(vp->v_interlock);
548 vp->v_numoutput++;
549 mutex_exit(vp->v_interlock);
550 }
551 VOP_STRATEGY(cs->sc_tvn, nbp);
552
553 return 0;
554 }
555
556 static void
557 cgdiodone(struct buf *nbp)
558 {
559 struct buf *obp = nbp->b_private;
560 struct cgd_softc *cs = getcgd_softc(obp->b_dev);
561 struct dk_softc *dksc = &cs->sc_dksc;
562 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
563 daddr_t bn;
564
565 KDASSERT(cs);
566
567 DPRINTF_FOLLOW(("cgdiodone(%p)\n", nbp));
568 DPRINTF(CGDB_IO, ("cgdiodone: bp %p bcount %d resid %d\n",
569 obp, obp->b_bcount, obp->b_resid));
570 DPRINTF(CGDB_IO, (" dev 0x%"PRIx64", nbp %p bn %" PRId64
571 " addr %p bcnt %d\n", nbp->b_dev, nbp, nbp->b_blkno, nbp->b_data,
572 nbp->b_bcount));
573 if (nbp->b_error != 0) {
574 obp->b_error = nbp->b_error;
575 DPRINTF(CGDB_IO, ("%s: error %d\n", dksc->sc_xname,
576 obp->b_error));
577 }
578
579 /* Perform the decryption if we are reading.
580 *
581 * Note: use the blocknumber from nbp, since it is what
582 * we used to encrypt the blocks.
583 */
584
585 if (nbp->b_flags & B_READ) {
586 bn = dbtob(nbp->b_blkno) / dg->dg_secsize;
587 cgd_cipher(cs, obp->b_data, obp->b_data, obp->b_bcount,
588 bn, dg->dg_secsize, CGD_CIPHER_DECRYPT);
589 }
590
591 /* If we allocated memory, free it now... */
592 if (nbp->b_data != obp->b_data)
593 cgd_putdata(dksc, nbp->b_data);
594
595 putiobuf(nbp);
596
597 /* Request is complete for whatever reason */
598 obp->b_resid = 0;
599 if (obp->b_error != 0)
600 obp->b_resid = obp->b_bcount;
601
602 dk_done(dksc, obp);
603 dk_start(dksc, NULL);
604 }
605
606 static int
607 cgd_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
608 {
609 struct cgd_softc *sc = device_private(dev);
610 struct dk_softc *dksc = &sc->sc_dksc;
611 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
612 size_t nbytes, blksize;
613 void *buf;
614 int error;
615
616 /*
617 * dk_dump gives us units of disklabel sectors. Everything
618 * else in cgd uses units of diskgeom sectors. These had
619 * better agree; otherwise we need to figure out how to convert
620 * between them.
621 */
622 KASSERTMSG((dg->dg_secsize == dksc->sc_dkdev.dk_label->d_secsize),
623 "diskgeom secsize %"PRIu32" != disklabel secsize %"PRIu32,
624 dg->dg_secsize, dksc->sc_dkdev.dk_label->d_secsize);
625 blksize = dg->dg_secsize;
626
627 /*
628 * Compute the number of bytes in this request, which dk_dump
629 * has `helpfully' converted to a number of blocks for us.
630 */
631 nbytes = nblk*blksize;
632
633 /* Try to acquire a buffer to store the ciphertext. */
634 buf = cgd_getdata(dksc, nbytes);
635 if (buf == NULL)
636 /* Out of memory: give up. */
637 return ENOMEM;
638
639 /* Encrypt the caller's data into the temporary buffer. */
640 cgd_cipher(sc, buf, va, nbytes, blkno, blksize, CGD_CIPHER_ENCRYPT);
641
642 /* Pass it on to the underlying disk device. */
643 error = bdev_dump(sc->sc_tdev, blkno, buf, nbytes);
644
645 /* Release the buffer. */
646 cgd_putdata(dksc, buf);
647
648 /* Return any error from the underlying disk device. */
649 return error;
650 }
651
652 /* XXX: we should probably put these into dksubr.c, mostly */
653 static int
654 cgdread(dev_t dev, struct uio *uio, int flags)
655 {
656 struct cgd_softc *cs;
657 struct dk_softc *dksc;
658
659 DPRINTF_FOLLOW(("cgdread(0x%llx, %p, %d)\n",
660 (unsigned long long)dev, uio, flags));
661 GETCGD_SOFTC(cs, dev);
662 dksc = &cs->sc_dksc;
663 if (!DK_ATTACHED(dksc))
664 return ENXIO;
665 return physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
666 }
667
668 /* XXX: we should probably put these into dksubr.c, mostly */
669 static int
670 cgdwrite(dev_t dev, struct uio *uio, int flags)
671 {
672 struct cgd_softc *cs;
673 struct dk_softc *dksc;
674
675 DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags));
676 GETCGD_SOFTC(cs, dev);
677 dksc = &cs->sc_dksc;
678 if (!DK_ATTACHED(dksc))
679 return ENXIO;
680 return physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio);
681 }
682
683 static int
684 cgdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
685 {
686 struct cgd_softc *cs;
687 struct dk_softc *dksc;
688 int part = DISKPART(dev);
689 int pmask = 1 << part;
690
691 DPRINTF_FOLLOW(("cgdioctl(0x%"PRIx64", %ld, %p, %d, %p)\n",
692 dev, cmd, data, flag, l));
693
694 switch (cmd) {
695 case CGDIOCGET:
696 return cgd_ioctl_get(dev, data, l);
697 case CGDIOCSET:
698 case CGDIOCCLR:
699 if ((flag & FWRITE) == 0)
700 return EBADF;
701 /* FALLTHROUGH */
702 default:
703 GETCGD_SOFTC(cs, dev);
704 dksc = &cs->sc_dksc;
705 break;
706 }
707
708 switch (cmd) {
709 case CGDIOCSET:
710 if (DK_ATTACHED(dksc))
711 return EBUSY;
712 return cgd_ioctl_set(cs, data, l);
713 case CGDIOCCLR:
714 if (DK_BUSY(&cs->sc_dksc, pmask))
715 return EBUSY;
716 return cgd_ioctl_clr(cs, l);
717 case DIOCGCACHE:
718 case DIOCCACHESYNC:
719 if (!DK_ATTACHED(dksc))
720 return ENOENT;
721 /*
722 * We pass this call down to the underlying disk.
723 */
724 return VOP_IOCTL(cs->sc_tvn, cmd, data, flag, l->l_cred);
725 case DIOCGSTRATEGY:
726 case DIOCSSTRATEGY:
727 if (!DK_ATTACHED(dksc))
728 return ENOENT;
729 /*FALLTHROUGH*/
730 default:
731 return dk_ioctl(dksc, dev, cmd, data, flag, l);
732 case CGDIOCGET:
733 KASSERT(0);
734 return EINVAL;
735 }
736 }
737
738 static int
739 cgddump(dev_t dev, daddr_t blkno, void *va, size_t size)
740 {
741 struct cgd_softc *cs;
742
743 DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n",
744 dev, blkno, va, (unsigned long)size));
745 GETCGD_SOFTC(cs, dev);
746 return dk_dump(&cs->sc_dksc, dev, blkno, va, size);
747 }
748
749 /*
750 * XXXrcd:
751 * for now we hardcode the maximum key length.
752 */
753 #define MAX_KEYSIZE 1024
754
755 static const struct {
756 const char *n;
757 int v;
758 int d;
759 } encblkno[] = {
760 { "encblkno", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
761 { "encblkno8", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
762 { "encblkno1", CGD_CIPHER_CBC_ENCBLKNO1, 8 },
763 };
764
765 /* ARGSUSED */
766 static int
767 cgd_ioctl_set(struct cgd_softc *cs, void *data, struct lwp *l)
768 {
769 struct cgd_ioctl *ci = data;
770 struct vnode *vp;
771 int ret;
772 size_t i;
773 size_t keybytes; /* key length in bytes */
774 const char *cp;
775 struct pathbuf *pb;
776 char *inbuf;
777 struct dk_softc *dksc = &cs->sc_dksc;
778
779 cp = ci->ci_disk;
780
781 ret = pathbuf_copyin(ci->ci_disk, &pb);
782 if (ret != 0) {
783 return ret;
784 }
785 ret = dk_lookup(pb, l, &vp);
786 pathbuf_destroy(pb);
787 if (ret != 0) {
788 return ret;
789 }
790
791 inbuf = malloc(MAX_KEYSIZE, M_TEMP, M_WAITOK);
792
793 if ((ret = cgdinit(cs, cp, vp, l)) != 0)
794 goto bail;
795
796 (void)memset(inbuf, 0, MAX_KEYSIZE);
797 ret = copyinstr(ci->ci_alg, inbuf, 256, NULL);
798 if (ret)
799 goto bail;
800 cs->sc_cfuncs = cryptfuncs_find(inbuf);
801 if (!cs->sc_cfuncs) {
802 ret = EINVAL;
803 goto bail;
804 }
805
806 (void)memset(inbuf, 0, MAX_KEYSIZE);
807 ret = copyinstr(ci->ci_ivmethod, inbuf, MAX_KEYSIZE, NULL);
808 if (ret)
809 goto bail;
810
811 for (i = 0; i < __arraycount(encblkno); i++)
812 if (strcmp(encblkno[i].n, inbuf) == 0)
813 break;
814
815 if (i == __arraycount(encblkno)) {
816 ret = EINVAL;
817 goto bail;
818 }
819
820 keybytes = ci->ci_keylen / 8 + 1;
821 if (keybytes > MAX_KEYSIZE) {
822 ret = EINVAL;
823 goto bail;
824 }
825
826 (void)memset(inbuf, 0, MAX_KEYSIZE);
827 ret = copyin(ci->ci_key, inbuf, keybytes);
828 if (ret)
829 goto bail;
830
831 cs->sc_cdata.cf_blocksize = ci->ci_blocksize;
832 cs->sc_cdata.cf_mode = encblkno[i].v;
833 cs->sc_cdata.cf_keylen = ci->ci_keylen;
834 cs->sc_cdata.cf_priv = cs->sc_cfuncs->cf_init(ci->ci_keylen, inbuf,
835 &cs->sc_cdata.cf_blocksize);
836 if (cs->sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE) {
837 log(LOG_WARNING, "cgd: Disallowed cipher with blocksize %zu > %u\n",
838 cs->sc_cdata.cf_blocksize, CGD_MAXBLOCKSIZE);
839 cs->sc_cdata.cf_priv = NULL;
840 }
841
842 /*
843 * The blocksize is supposed to be in bytes. Unfortunately originally
844 * it was expressed in bits. For compatibility we maintain encblkno
845 * and encblkno8.
846 */
847 cs->sc_cdata.cf_blocksize /= encblkno[i].d;
848 (void)explicit_memset(inbuf, 0, MAX_KEYSIZE);
849 if (!cs->sc_cdata.cf_priv) {
850 ret = EINVAL; /* XXX is this the right error? */
851 goto bail;
852 }
853 free(inbuf, M_TEMP);
854
855 bufq_alloc(&dksc->sc_bufq, "fcfs", 0);
856
857 cs->sc_data = malloc(MAXPHYS, M_DEVBUF, M_WAITOK);
858 cs->sc_data_used = 0;
859
860 /* Attach the disk. */
861 dk_attach(dksc);
862 disk_attach(&dksc->sc_dkdev);
863
864 disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
865
866 /* Discover wedges on this disk. */
867 dkwedge_discover(&dksc->sc_dkdev);
868
869 return 0;
870
871 bail:
872 free(inbuf, M_TEMP);
873 (void)vn_close(vp, FREAD|FWRITE, l->l_cred);
874 return ret;
875 }
876
877 /* ARGSUSED */
878 static int
879 cgd_ioctl_clr(struct cgd_softc *cs, struct lwp *l)
880 {
881 struct dk_softc *dksc = &cs->sc_dksc;
882
883 if (!DK_ATTACHED(dksc))
884 return ENXIO;
885
886 /* Delete all of our wedges. */
887 dkwedge_delall(&dksc->sc_dkdev);
888
889 /* Kill off any queued buffers. */
890 dk_drain(dksc);
891 bufq_free(dksc->sc_bufq);
892
893 (void)vn_close(cs->sc_tvn, FREAD|FWRITE, l->l_cred);
894 cs->sc_cfuncs->cf_destroy(cs->sc_cdata.cf_priv);
895 free(cs->sc_tpath, M_DEVBUF);
896 free(cs->sc_data, M_DEVBUF);
897 cs->sc_data_used = 0;
898 dk_detach(dksc);
899 disk_detach(&dksc->sc_dkdev);
900
901 return 0;
902 }
903
904 static int
905 cgd_ioctl_get(dev_t dev, void *data, struct lwp *l)
906 {
907 struct cgd_softc *cs = getcgd_softc(dev);
908 struct cgd_user *cgu;
909 int unit;
910 struct dk_softc *dksc = &cs->sc_dksc;
911
912 unit = CGDUNIT(dev);
913 cgu = (struct cgd_user *)data;
914
915 DPRINTF_FOLLOW(("cgd_ioctl_get(0x%"PRIx64", %d, %p, %p)\n",
916 dev, unit, data, l));
917
918 if (cgu->cgu_unit == -1)
919 cgu->cgu_unit = unit;
920
921 if (cgu->cgu_unit < 0)
922 return EINVAL; /* XXX: should this be ENXIO? */
923
924 cs = device_lookup_private(&cgd_cd, unit);
925 if (cs == NULL || !DK_ATTACHED(dksc)) {
926 cgu->cgu_dev = 0;
927 cgu->cgu_alg[0] = '\0';
928 cgu->cgu_blocksize = 0;
929 cgu->cgu_mode = 0;
930 cgu->cgu_keylen = 0;
931 }
932 else {
933 cgu->cgu_dev = cs->sc_tdev;
934 strlcpy(cgu->cgu_alg, cs->sc_cfuncs->cf_name,
935 sizeof(cgu->cgu_alg));
936 cgu->cgu_blocksize = cs->sc_cdata.cf_blocksize;
937 cgu->cgu_mode = cs->sc_cdata.cf_mode;
938 cgu->cgu_keylen = cs->sc_cdata.cf_keylen;
939 }
940 return 0;
941 }
942
943 static int
944 cgdinit(struct cgd_softc *cs, const char *cpath, struct vnode *vp,
945 struct lwp *l)
946 {
947 struct disk_geom *dg;
948 int ret;
949 char *tmppath;
950 uint64_t psize;
951 unsigned secsize;
952 struct dk_softc *dksc = &cs->sc_dksc;
953
954 cs->sc_tvn = vp;
955 cs->sc_tpath = NULL;
956
957 tmppath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
958 ret = copyinstr(cpath, tmppath, MAXPATHLEN, &cs->sc_tpathlen);
959 if (ret)
960 goto bail;
961 cs->sc_tpath = malloc(cs->sc_tpathlen, M_DEVBUF, M_WAITOK);
962 memcpy(cs->sc_tpath, tmppath, cs->sc_tpathlen);
963
964 cs->sc_tdev = vp->v_rdev;
965
966 if ((ret = getdisksize(vp, &psize, &secsize)) != 0)
967 goto bail;
968
969 if (psize == 0) {
970 ret = ENODEV;
971 goto bail;
972 }
973
974 /*
975 * XXX here we should probe the underlying device. If we
976 * are accessing a partition of type RAW_PART, then
977 * we should populate our initial geometry with the
978 * geometry that we discover from the device.
979 */
980 dg = &dksc->sc_dkdev.dk_geom;
981 memset(dg, 0, sizeof(*dg));
982 dg->dg_secperunit = psize;
983 dg->dg_secsize = secsize;
984 dg->dg_ntracks = 1;
985 dg->dg_nsectors = 1024 * 1024 / dg->dg_secsize;
986 dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors;
987
988 bail:
989 free(tmppath, M_TEMP);
990 if (ret && cs->sc_tpath)
991 free(cs->sc_tpath, M_DEVBUF);
992 return ret;
993 }
994
995 /*
996 * Our generic cipher entry point. This takes care of the
997 * IV mode and passes off the work to the specific cipher.
998 * We implement here the IV method ``encrypted block
999 * number''.
1000 *
1001 * XXXrcd: for now we rely on our own crypto framework defined
1002 * in dev/cgd_crypto.c. This will change when we
1003 * get a generic kernel crypto framework.
1004 */
1005
1006 static void
1007 blkno2blkno_buf(char *sbuf, daddr_t blkno)
1008 {
1009 int i;
1010
1011 /* Set up the blkno in blkno_buf, here we do not care much
1012 * about the final layout of the information as long as we
1013 * can guarantee that each sector will have a different IV
1014 * and that the endianness of the machine will not affect
1015 * the representation that we have chosen.
1016 *
1017 * We choose this representation, because it does not rely
1018 * on the size of buf (which is the blocksize of the cipher),
1019 * but allows daddr_t to grow without breaking existing
1020 * disks.
1021 *
1022 * Note that blkno2blkno_buf does not take a size as input,
1023 * and hence must be called on a pre-zeroed buffer of length
1024 * greater than or equal to sizeof(daddr_t).
1025 */
1026 for (i=0; i < sizeof(daddr_t); i++) {
1027 *sbuf++ = blkno & 0xff;
1028 blkno >>= 8;
1029 }
1030 }
1031
1032 static void
1033 cgd_cipher(struct cgd_softc *cs, void *dstv, void *srcv,
1034 size_t len, daddr_t blkno, size_t secsize, int dir)
1035 {
1036 char *dst = dstv;
1037 char *src = srcv;
1038 cfunc_cipher_prep *ciprep = cs->sc_cfuncs->cf_cipher_prep;
1039 cfunc_cipher *cipher = cs->sc_cfuncs->cf_cipher;
1040 struct uio dstuio;
1041 struct uio srcuio;
1042 struct iovec dstiov[2];
1043 struct iovec srciov[2];
1044 size_t blocksize = cs->sc_cdata.cf_blocksize;
1045 size_t todo;
1046 char blkno_buf[CGD_MAXBLOCKSIZE], *iv;
1047
1048 DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir));
1049
1050 DIAGCONDPANIC(len % blocksize != 0,
1051 ("cgd_cipher: len %% blocksize != 0"));
1052
1053 /* ensure that sizeof(daddr_t) <= blocksize (for encblkno IVing) */
1054 DIAGCONDPANIC(sizeof(daddr_t) > blocksize,
1055 ("cgd_cipher: sizeof(daddr_t) > blocksize"));
1056
1057 DIAGCONDPANIC(blocksize > CGD_MAXBLOCKSIZE,
1058 ("cgd_cipher: blocksize > CGD_MAXBLOCKSIZE"));
1059
1060 dstuio.uio_iov = dstiov;
1061 dstuio.uio_iovcnt = 1;
1062
1063 srcuio.uio_iov = srciov;
1064 srcuio.uio_iovcnt = 1;
1065
1066 for (; len > 0; len -= todo) {
1067 todo = MIN(len, secsize);
1068
1069 dstiov[0].iov_base = dst;
1070 srciov[0].iov_base = src;
1071 dstiov[0].iov_len = todo;
1072 srciov[0].iov_len = todo;
1073
1074 memset(blkno_buf, 0x0, blocksize);
1075 blkno2blkno_buf(blkno_buf, blkno);
1076 IFDEBUG(CGDB_CRYPTO, hexprint("step 1: blkno_buf",
1077 blkno_buf, blocksize));
1078
1079 /*
1080 * Compute an initial IV. All ciphers
1081 * can convert blkno_buf in-place.
1082 */
1083 iv = blkno_buf;
1084 ciprep(cs->sc_cdata.cf_priv, iv, blkno_buf, blocksize, dir);
1085 IFDEBUG(CGDB_CRYPTO, hexprint("step 2: iv", iv, blocksize));
1086
1087 cipher(cs->sc_cdata.cf_priv, &dstuio, &srcuio, iv, dir);
1088
1089 dst += todo;
1090 src += todo;
1091 blkno++;
1092 }
1093 }
1094
1095 #ifdef DEBUG
1096 static void
1097 hexprint(const char *start, void *buf, int len)
1098 {
1099 char *c = buf;
1100
1101 DIAGCONDPANIC(len < 0, ("hexprint: called with len < 0"));
1102 printf("%s: len=%06d 0x", start, len);
1103 while (len--)
1104 printf("%02x", (unsigned char) *c++);
1105 }
1106 #endif
1107
1108 static void
1109 selftest(void)
1110 {
1111 struct cgd_softc cs;
1112 void *buf;
1113
1114 printf("running cgd selftest ");
1115
1116 for (size_t i = 0; i < __arraycount(selftests); i++) {
1117 const char *alg = selftests[i].alg;
1118 const uint8_t *key = selftests[i].key;
1119 int keylen = selftests[i].keylen;
1120 int txtlen = selftests[i].txtlen;
1121
1122 printf("%s-%d ", alg, keylen);
1123
1124 memset(&cs, 0, sizeof(cs));
1125
1126 cs.sc_cfuncs = cryptfuncs_find(alg);
1127 if (cs.sc_cfuncs == NULL)
1128 panic("%s not implemented", alg);
1129
1130 cs.sc_cdata.cf_blocksize = 8 * selftests[i].blocksize;
1131 cs.sc_cdata.cf_mode = CGD_CIPHER_CBC_ENCBLKNO1;
1132 cs.sc_cdata.cf_keylen = keylen;
1133
1134 cs.sc_cdata.cf_priv = cs.sc_cfuncs->cf_init(keylen,
1135 key, &cs.sc_cdata.cf_blocksize);
1136 if (cs.sc_cdata.cf_priv == NULL)
1137 panic("cf_priv is NULL");
1138 if (cs.sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE)
1139 panic("bad block size %zu", cs.sc_cdata.cf_blocksize);
1140
1141 cs.sc_cdata.cf_blocksize /= 8;
1142
1143 buf = malloc(txtlen, M_DEVBUF, M_WAITOK);
1144 memcpy(buf, selftests[i].ptxt, txtlen);
1145
1146 cgd_cipher(&cs, buf, buf, txtlen, selftests[i].blkno,
1147 selftests[i].secsize, CGD_CIPHER_ENCRYPT);
1148 if (memcmp(buf, selftests[i].ctxt, txtlen) != 0)
1149 panic("encryption is broken");
1150
1151 cgd_cipher(&cs, buf, buf, txtlen, selftests[i].blkno,
1152 selftests[i].secsize, CGD_CIPHER_DECRYPT);
1153 if (memcmp(buf, selftests[i].ptxt, txtlen) != 0)
1154 panic("decryption is broken");
1155
1156 free(buf, M_DEVBUF);
1157 cs.sc_cfuncs->cf_destroy(cs.sc_cdata.cf_priv);
1158 }
1159
1160 printf("done\n");
1161 }
1162
1163 MODULE(MODULE_CLASS_DRIVER, cgd, "blowfish,des,dk_subr,bufq_fcfs");
1164
1165 #ifdef _MODULE
1166 CFDRIVER_DECL(cgd, DV_DISK, NULL);
1167
1168 devmajor_t cgd_bmajor = -1, cgd_cmajor = -1;
1169 #endif
1170
1171 static int
1172 cgd_modcmd(modcmd_t cmd, void *arg)
1173 {
1174 int error = 0;
1175
1176 switch (cmd) {
1177 case MODULE_CMD_INIT:
1178 selftest();
1179 #ifdef _MODULE
1180 error = config_cfdriver_attach(&cgd_cd);
1181 if (error)
1182 break;
1183
1184 error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
1185 if (error) {
1186 config_cfdriver_detach(&cgd_cd);
1187 aprint_error("%s: unable to register cfattach for"
1188 "%s, error %d\n", __func__, cgd_cd.cd_name, error);
1189 break;
1190 }
1191 /*
1192 * Attach the {b,c}devsw's
1193 */
1194 error = devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
1195 &cgd_cdevsw, &cgd_cmajor);
1196
1197 /*
1198 * If devsw_attach fails, remove from autoconf database
1199 */
1200 if (error) {
1201 config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
1202 config_cfdriver_detach(&cgd_cd);
1203 aprint_error("%s: unable to attach %s devsw, "
1204 "error %d", __func__, cgd_cd.cd_name, error);
1205 break;
1206 }
1207 #endif
1208 break;
1209
1210 case MODULE_CMD_FINI:
1211 #ifdef _MODULE
1212 /*
1213 * Remove {b,c}devsw's
1214 */
1215 devsw_detach(&cgd_bdevsw, &cgd_cdevsw);
1216
1217 /*
1218 * Now remove device from autoconf database
1219 */
1220 error = config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
1221 if (error) {
1222 (void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
1223 &cgd_cdevsw, &cgd_cmajor);
1224 aprint_error("%s: failed to detach %s cfattach, "
1225 "error %d\n", __func__, cgd_cd.cd_name, error);
1226 break;
1227 }
1228 error = config_cfdriver_detach(&cgd_cd);
1229 if (error) {
1230 (void)config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
1231 (void)devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
1232 &cgd_cdevsw, &cgd_cmajor);
1233 aprint_error("%s: failed to detach %s cfdriver, "
1234 "error %d\n", __func__, cgd_cd.cd_name, error);
1235 break;
1236 }
1237 #endif
1238 break;
1239
1240 case MODULE_CMD_STAT:
1241 error = ENOTTY;
1242 break;
1243 default:
1244 error = ENOTTY;
1245 break;
1246 }
1247
1248 return error;
1249 }
1250