/*- * 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 #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_ */