summaryrefslogtreecommitdiff
path: root/crypto/external/bsd/netpgp/dist/src/lib/crypto.h
blob: ff631efedf2a60f37c13ca0c8d569dfa77fc0e31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/*-
 * Copyright (c) 2009 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Alistair Crooks (agc@NetBSD.org)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
 * All rights reserved.
 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
 * their moral rights under the UK Copyright Design and Patents Act 1988 to
 * be recorded as the authors of this copyright work.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** \file
 */

#ifndef CRYPTO_H_
#define CRYPTO_H_

#include "keyring.h"
#include "packet.h"
#include "memory.h"
#include "packet-parse.h"

#include <openssl/dsa.h>

#define PGP_MIN_HASH_SIZE	16

/** pgp_hash_t */
struct pgp_hash_t {
	pgp_hash_alg_t		 alg;		/* algorithm */
	size_t			 size;		/* size */
	const char		*name;		/* what it's known as */
	int			(*init)(pgp_hash_t *);
	void			(*add)(pgp_hash_t *, const uint8_t *, unsigned);
	unsigned		(*finish)(pgp_hash_t *, uint8_t *);
	void		 	*data;		/* blob for data */
};

/** pgp_crypt_t */
struct pgp_crypt_t {
	pgp_symm_alg_t	alg;
	size_t			blocksize;
	size_t			keysize;
	void 			(*set_iv)(pgp_crypt_t *, const uint8_t *);
	void			(*set_crypt_key)(pgp_crypt_t *, const uint8_t *);
	int			(*base_init)(pgp_crypt_t *);
	void			(*decrypt_resync)(pgp_crypt_t *);
	/* encrypt/decrypt one block */
	void			(*block_encrypt)(pgp_crypt_t *, void *, const void *);
	void			(*block_decrypt)(pgp_crypt_t *, void *, const void *);
	/* Standard CFB encrypt/decrypt (as used by Sym Enc Int Prot packets) */
	void 			(*cfb_encrypt)(pgp_crypt_t *, void *, const void *, size_t);
	void			(*cfb_decrypt)(pgp_crypt_t *, void *, const void *, size_t);
	void			(*decrypt_finish)(pgp_crypt_t *);
	uint8_t			iv[PGP_MAX_BLOCK_SIZE];
	uint8_t			civ[PGP_MAX_BLOCK_SIZE];
	uint8_t			siv[PGP_MAX_BLOCK_SIZE];
		/* siv is needed for weird v3 resync */
	uint8_t			key[PGP_MAX_KEY_SIZE];
	int			num;
		/* num is offset - see openssl _encrypt doco */
	void			*encrypt_key;
	void			*decrypt_key;
};

void pgp_crypto_finish(void);
void pgp_hash_md5(pgp_hash_t *);
void pgp_hash_sha1(pgp_hash_t *);
void pgp_hash_sha256(pgp_hash_t *);
void pgp_hash_sha512(pgp_hash_t *);
void pgp_hash_sha384(pgp_hash_t *);
void pgp_hash_sha224(pgp_hash_t *);
void pgp_hash_any(pgp_hash_t *, pgp_hash_alg_t);
pgp_hash_alg_t pgp_str_to_hash_alg(const char *);
const char *pgp_text_from_hash(pgp_hash_t *);
unsigned pgp_hash_size(pgp_hash_alg_t);
unsigned pgp_hash(uint8_t *, pgp_hash_alg_t, const void *, size_t);

void pgp_hash_add_int(pgp_hash_t *, unsigned, unsigned);

unsigned pgp_dsa_verify(const uint8_t *, size_t,
			const pgp_dsa_sig_t *,
			const pgp_dsa_pubkey_t *);

int pgp_rsa_public_decrypt(uint8_t *, const uint8_t *, size_t,
			const pgp_rsa_pubkey_t *);
int pgp_rsa_public_encrypt(uint8_t *, const uint8_t *, size_t,
			const pgp_rsa_pubkey_t *);

int pgp_rsa_private_encrypt(uint8_t *, const uint8_t *, size_t,
			const pgp_rsa_seckey_t *, const pgp_rsa_pubkey_t *);
int pgp_rsa_private_decrypt(uint8_t *, const uint8_t *, size_t,
			const pgp_rsa_seckey_t *, const pgp_rsa_pubkey_t *);

int pgp_elgamal_public_encrypt(uint8_t *, uint8_t *, const uint8_t *, size_t,
			const pgp_elgamal_pubkey_t *);
int pgp_elgamal_private_decrypt(uint8_t *, const uint8_t *, const uint8_t *, size_t,
			const pgp_elgamal_seckey_t *, const pgp_elgamal_pubkey_t *);

pgp_symm_alg_t pgp_str_to_cipher(const char *);
unsigned pgp_block_size(pgp_symm_alg_t);
unsigned pgp_key_size(pgp_symm_alg_t);

int pgp_decrypt_data(pgp_content_enum, pgp_region_t *,
			pgp_stream_t *);

int pgp_crypt_any(pgp_crypt_t *, pgp_symm_alg_t);
void pgp_decrypt_init(pgp_crypt_t *);
void pgp_encrypt_init(pgp_crypt_t *);
size_t pgp_decrypt_se(pgp_crypt_t *, void *, const void *, size_t);
size_t pgp_encrypt_se(pgp_crypt_t *, void *, const void *, size_t);
size_t pgp_decrypt_se_ip(pgp_crypt_t *, void *, const void *, size_t);
size_t pgp_encrypt_se_ip(pgp_crypt_t *, void *, const void *, size_t);
unsigned pgp_is_sa_supported(pgp_symm_alg_t);

void pgp_reader_push_decrypt(pgp_stream_t *, pgp_crypt_t *,
			pgp_region_t *);
void pgp_reader_pop_decrypt(pgp_stream_t *);

/* Hash everything that's read */
void pgp_reader_push_hash(pgp_stream_t *, pgp_hash_t *);
void pgp_reader_pop_hash(pgp_stream_t *);

int pgp_decrypt_decode_mpi(uint8_t *, unsigned, const BIGNUM *,
			const BIGNUM *, const pgp_seckey_t *);

unsigned pgp_rsa_encrypt_mpi(const uint8_t *, const size_t,
			const pgp_pubkey_t *,
			pgp_pk_sesskey_params_t *);
unsigned pgp_elgamal_encrypt_mpi(const uint8_t *, const size_t,
			const pgp_pubkey_t *,
			pgp_pk_sesskey_params_t *);

/* Encrypt everything that's written */
struct pgp_key_data;
void pgp_writer_push_encrypt(pgp_output_t *,
			const struct pgp_key_data *);

unsigned   pgp_encrypt_file(pgp_io_t *, const char *, const char *,
			const pgp_key_t *,
			const unsigned, const unsigned, const char *);
unsigned   pgp_decrypt_file(pgp_io_t *,
			const char *,
			const char *,
			pgp_keyring_t *,
			pgp_keyring_t *,
			const unsigned,
			const unsigned,
			const unsigned,
			void *,
			int,
			pgp_cbfunc_t *);

pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *, const void *, const size_t,
			const pgp_key_t *,
			const unsigned, const char *);
pgp_memory_t *
pgp_decrypt_buf(pgp_io_t *,
			const void *,
			const size_t,
			pgp_keyring_t *,
			pgp_keyring_t *,
			const unsigned,
			const unsigned,
			void *,
			int,
			pgp_cbfunc_t *);

/* Keys */
pgp_key_t  *pgp_rsa_new_selfsign_key(const int,
			const unsigned long, uint8_t *, const char *,
			const char *);

int pgp_dsa_size(const pgp_dsa_pubkey_t *);
DSA_SIG *pgp_dsa_sign(uint8_t *, unsigned,
				const pgp_dsa_seckey_t *,
				const pgp_dsa_pubkey_t *);

int openssl_read_pem_seckey(const char *, pgp_key_t *, const char *, int);

/** pgp_reader_t */
struct pgp_reader_t {
	pgp_reader_func_t	*reader; /* reader func to get parse data */
	pgp_reader_destroyer_t	*destroyer;
	void			*arg;	/* args to pass to reader function */
	unsigned		 accumulate:1;	/* set to gather packet data */
	uint8_t			*accumulated;	/* the accumulated data */
	unsigned		 asize;	/* size of the buffer */
	unsigned		 alength;/* used buffer */
	unsigned		 position;	/* reader-specific offset */
	pgp_reader_t		*next;
	pgp_stream_t		*parent;/* parent parse_info structure */
};


/** pgp_cryptinfo_t
 Encrypt/decrypt settings
*/
struct pgp_cryptinfo_t {
	char			*passphrase;
	pgp_keyring_t		*secring;
	const pgp_key_t		*keydata;
	pgp_cbfunc_t		*getpassphrase;
	pgp_keyring_t		*pubring;
};

/** pgp_cbdata_t */
struct pgp_cbdata_t {
	pgp_cbfunc_t		*cbfunc;	/* callback function */
	void			*arg;	/* args to pass to callback func */
	pgp_error_t		**errors; /* address of error stack */
	pgp_cbdata_t		*next;
	pgp_output_t		*output;	/* when writing out parsed info */
	pgp_io_t		*io;		/* error/output messages */
	void			*passfp;	/* fp for passphrase input */
	pgp_cryptinfo_t		 cryptinfo;	/* used when decrypting */
	pgp_printstate_t	 printstate;	/* used to keep printing state */
	pgp_seckey_t		*sshseckey;	/* secret key for ssh */
	int			 numtries;	/* # of passphrase attempts */
	int			 gotpass;	/* when passphrase entered */
};

/** pgp_hashtype_t */
typedef struct {
	pgp_hash_t	hash;	/* hashes we should hash data with */
	uint8_t	keyid[PGP_KEY_ID_SIZE];
} pgp_hashtype_t;

#define NTAGS	0x100	/* == 256 */

/** \brief Structure to hold information about a packet parse.
 *
 *  This information includes options about the parse:
 *  - whether the packet contents should be accumulated or not
 *  - whether signature subpackets should be parsed or left raw
 *
 *  It contains options specific to the parsing of armoured data:
 *  - whether headers are allowed in armoured data without a gap
 *  - whether a blank line is allowed at the start of the armoured data
 *
 *  It also specifies :
 *  - the callback function to use and its arguments
 *  - the reader function to use and its arguments
 *
 *  It also contains information about the current state of the parse:
 *  - offset from the beginning
 *  - the accumulated data, if any
 *  - the size of the buffer, and how much has been used
 *
 *  It has a linked list of errors.
 */

struct pgp_stream_t {
	uint8_t		 	ss_raw[NTAGS / 8];
		/* 1 bit / sig-subpkt type; set to get raw data */
	uint8_t		 	ss_parsed[NTAGS / 8];
		/* 1 bit / sig-subpkt type; set to get parsed data */
	pgp_reader_t	 	 readinfo;
	pgp_cbdata_t		 cbinfo;
	pgp_error_t		*errors;
	void			*io;		/* io streams */
	pgp_crypt_t		 decrypt;
	pgp_cryptinfo_t		 cryptinfo;
	size_t			 hashc;
	pgp_hashtype_t		*hashes;
	unsigned		 reading_v3_secret:1;
	unsigned		 reading_mpi_len:1;
	unsigned		 exact_read:1;
	unsigned		 partial_read:1;
	unsigned		 coalescing:1;
	/* used for partial length coalescing */
	unsigned		 virtualc;
	unsigned		 virtualoff;
	uint8_t			*virtualpkt;
};

#endif /* CRYPTO_H_ */