1105464Sphk/*-
2105464Sphk * Copyright (c) 2002 Poul-Henning Kamp
3105464Sphk * Copyright (c) 2002 Networks Associates Technology, Inc.
4105464Sphk * All rights reserved.
5105464Sphk *
6105464Sphk * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7105464Sphk * and NAI Labs, the Security Research Division of Network Associates, Inc.
8105464Sphk * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9105464Sphk * DARPA CHATS research program.
10105464Sphk *
11105464Sphk * Redistribution and use in source and binary forms, with or without
12105464Sphk * modification, are permitted provided that the following conditions
13105464Sphk * are met:
14105464Sphk * 1. Redistributions of source code must retain the above copyright
15105464Sphk *    notice, this list of conditions and the following disclaimer.
16105464Sphk * 2. Redistributions in binary form must reproduce the above copyright
17105464Sphk *    notice, this list of conditions and the following disclaimer in the
18105464Sphk *    documentation and/or other materials provided with the distribution.
19105464Sphk *
20105464Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21105464Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22105464Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23105464Sphk * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24105464Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25105464Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26105464Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27105464Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28105464Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29105464Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30105464Sphk * SUCH DAMAGE.
31105464Sphk *
32105464Sphk * $FreeBSD$
33105464Sphk */
34105464Sphk
35106407Sphk#ifndef _SYS_GEOM_BDE_G_BDE_H_
36106407Sphk#define _SYS_GEOM_BDE_G_BDE_H_ 1
37106407Sphk
38106407Sphk/*
39106407Sphk * These are quite, but not entirely unlike constants.
40106407Sphk *
41106407Sphk * They are not commented in details here, to prevent unadvisable
42106407Sphk * experimentation. Please consult the code where they are used before you
43106407Sphk * even think about modifying these.
44106407Sphk */
45106407Sphk
46105464Sphk#define G_BDE_MKEYLEN	(2048/8)
47105464Sphk#define G_BDE_SKEYBITS	128
48105464Sphk#define G_BDE_SKEYLEN	(G_BDE_SKEYBITS/8)
49105464Sphk#define G_BDE_KKEYBITS	128
50105464Sphk#define G_BDE_KKEYLEN	(G_BDE_KKEYBITS/8)
51105464Sphk#define G_BDE_MAXKEYS	4
52105464Sphk#define G_BDE_LOCKSIZE	384
53106407Sphk#define NLOCK_FIELDS	13
54105464Sphk
55106407Sphk
56105464Sphk/* This just needs to be "large enough" */
57105464Sphk#define G_BDE_KEYBYTES	304
58105464Sphk
59105464Sphkstruct g_bde_work;
60105464Sphkstruct g_bde_softc;
61105464Sphk
62105464Sphkstruct g_bde_sector {
63105464Sphk	struct g_bde_work	*owner;
64105464Sphk	struct g_bde_softc	*softc;
65105464Sphk	off_t			offset;
66105464Sphk	u_int			size;
67105464Sphk	u_int			ref;
68105464Sphk	void			*data;
69105464Sphk	TAILQ_ENTRY(g_bde_sector) list;
70105464Sphk	u_char			valid;
71105464Sphk	u_char			malloc;
72105464Sphk	enum {JUNK, IO, VALID}	state;
73105464Sphk	int			error;
74106407Sphk	time_t			used;
75105464Sphk};
76105464Sphk
77105464Sphkstruct g_bde_work {
78105464Sphk	struct mtx		mutex;
79105464Sphk	off_t			offset;
80105464Sphk	off_t			length;
81105464Sphk	void			*data;
82105464Sphk        struct bio      	*bp;
83105464Sphk	struct g_bde_softc 	*softc;
84105464Sphk        off_t           	so;
85105464Sphk        off_t           	kso;
86105464Sphk        u_int           	ko;
87105464Sphk        struct g_bde_sector   	*sp;
88105464Sphk        struct g_bde_sector   	*ksp;
89105464Sphk	TAILQ_ENTRY(g_bde_work) list;
90105464Sphk	enum {SETUP, WAIT, FINISH} state;
91105464Sphk	int			error;
92105464Sphk};
93105464Sphk
94106407Sphk/*
95106407Sphk * The decrypted contents of the lock sectors.  Notice that this is not
96106407Sphk * the same as the on-disk layout.  The on-disk layout is dynamic and
97106407Sphk * dependent on the pass-phrase.
98106407Sphk */
99105464Sphkstruct g_bde_key {
100105464Sphk	uint64_t		sector0;
101106407Sphk				/* Physical byte offset of 1st byte used */
102105464Sphk	uint64_t		sectorN;
103106407Sphk				/* Physical byte offset of 1st byte not used */
104105464Sphk	uint64_t		keyoffset;
105106407Sphk				/* Number of bytes the disk image is skewed. */
106105464Sphk	uint64_t		lsector[G_BDE_MAXKEYS];
107106407Sphk				/* Physical byte offsets of lock sectors */
108105464Sphk	uint32_t		sectorsize;
109106407Sphk				/* Our "logical" sector size */
110105464Sphk	uint32_t		flags;
111120876Sphk#define	GBDE_F_SECT0		1
112106226Sphk	uint8_t			salt[16];
113106407Sphk				/* Used to frustate the kkey generation */
114106226Sphk	uint8_t			spare[32];
115106407Sphk				/* For future use, random contents */
116106226Sphk	uint8_t			mkey[G_BDE_MKEYLEN];
117106407Sphk				/* Our masterkey. */
118106407Sphk
119105464Sphk	/* Non-stored help-fields */
120105464Sphk	uint64_t		zone_width;	/* On-disk width of zone */
121105464Sphk	uint64_t		zone_cont;	/* Payload width of zone */
122105464Sphk	uint64_t		media_width;	/* Non-magic width of zone */
123105464Sphk	u_int			keys_per_sector;
124105464Sphk};
125105464Sphk
126105464Sphkstruct g_bde_softc {
127105464Sphk	off_t			mediasize;
128105464Sphk	u_int			sectorsize;
129105464Sphk	uint64_t		zone_cont;
130105464Sphk	struct g_geom		*geom;
131105464Sphk	struct g_consumer	*consumer;
132105464Sphk	TAILQ_HEAD(, g_bde_sector)	freelist;
133105464Sphk	TAILQ_HEAD(, g_bde_work) 	worklist;
134105464Sphk	struct mtx		worklist_mutex;
135105464Sphk	struct proc		*thread;
136105464Sphk	struct g_bde_key	key;
137105464Sphk	int			dead;
138105464Sphk	u_int			nwork;
139105464Sphk	u_int			nsect;
140105464Sphk	u_int			ncache;
141106407Sphk	u_char			sha2[SHA512_DIGEST_LENGTH];
142105464Sphk};
143105464Sphk
144105464Sphk/* g_bde_crypt.c */
145105464Sphkvoid g_bde_crypt_delete(struct g_bde_work *wp);
146105464Sphkvoid g_bde_crypt_read(struct g_bde_work *wp);
147105464Sphkvoid g_bde_crypt_write(struct g_bde_work *wp);
148105464Sphk
149105464Sphk/* g_bde_key.c */
150105464Sphkvoid g_bde_zap_key(struct g_bde_softc *sc);
151105464Sphkint g_bde_get_key(struct g_bde_softc *sc, void *ptr, int len);
152105464Sphkint g_bde_init_keybytes(struct g_bde_softc *sc, char *passp, int len);
153105464Sphk
154105464Sphk/* g_bde_lock .c */
155120876Sphkint g_bde_encode_lock(u_char *sha2, struct g_bde_key *gl, u_char *ptr);
156106407Sphkint g_bde_decode_lock(struct g_bde_softc *sc, struct g_bde_key *gl, u_char *ptr);
157120876Sphkint g_bde_keyloc_encrypt(u_char *sha2, uint64_t v0, uint64_t v1, void *output);
158120876Sphkint g_bde_keyloc_decrypt(u_char *sha2, void *input, uint64_t *output);
159106407Sphkint g_bde_decrypt_lock(struct g_bde_softc *sc, u_char *keymat, u_char *meta, off_t mediasize, u_int sectorsize, u_int *nkey);
160106407Sphkvoid g_bde_hash_pass(struct g_bde_softc *sc, const void *input, u_int len);
161105464Sphk
162105464Sphk/* g_bde_math .c */
163105464Sphkuint64_t g_bde_max_sector(struct g_bde_key *lp);
164108558Sphkvoid g_bde_map_sector(struct g_bde_work *wp);
165105464Sphk
166105464Sphk/* g_bde_work.c */
167105464Sphkvoid g_bde_start1(struct bio *bp);
168105464Sphkvoid g_bde_worker(void *arg);
169105464Sphk
170106407Sphk/*
171106407Sphk * These four functions wrap the raw Rijndael functions and make sure we
172106407Sphk * explode if something fails which shouldn't.
173106407Sphk */
174106407Sphk
175106407Sphkstatic __inline void
176106407SphkAES_init(cipherInstance *ci)
177106407Sphk{
178106407Sphk	int error;
179106407Sphk
180106407Sphk	error = rijndael_cipherInit(ci, MODE_CBC, NULL);
181106407Sphk	KASSERT(error > 0, ("rijndael_cipherInit %d", error));
182106407Sphk}
183106407Sphk
184106407Sphkstatic __inline void
185274340SdesAES_makekey(keyInstance *ki, int dir, u_int len, const void *key)
186106407Sphk{
187106407Sphk	int error;
188106407Sphk
189106407Sphk	error = rijndael_makeKey(ki, dir, len, key);
190106407Sphk	KASSERT(error > 0, ("rijndael_makeKey %d", error));
191106407Sphk}
192106407Sphk
193106407Sphkstatic __inline void
194274340SdesAES_encrypt(cipherInstance *ci, keyInstance *ki, const void *in, void *out, u_int len)
195106407Sphk{
196106407Sphk	int error;
197106407Sphk
198106407Sphk	error = rijndael_blockEncrypt(ci, ki, in, len * 8, out);
199106407Sphk	KASSERT(error > 0, ("rijndael_blockEncrypt %d", error));
200106407Sphk}
201106407Sphk
202106407Sphkstatic __inline void
203274340SdesAES_decrypt(cipherInstance *ci, keyInstance *ki, const void *in, void *out, u_int len)
204106407Sphk{
205106407Sphk	int error;
206106407Sphk
207106407Sphk	error = rijndael_blockDecrypt(ci, ki, in, len * 8, out);
208106407Sphk	KASSERT(error > 0, ("rijndael_blockDecrypt %d", error));
209106407Sphk}
210106407Sphk
211106407Sphk#endif /* _SYS_GEOM_BDE_G_BDE_H_ */
212