/*- * Copyright (c) 2017 Ribose Inc. * All rights reserved. * * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDERS 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. */ #ifndef ECDH_H_ #define ECDH_H_ #include "crypto/ec.h" /* Max size of wrapped and obfuscated key size * * RNP pads a key with PKCS-5 always to 8 byte granularity, * then 8 bytes is added by AES-wrap (RFC3394). */ #define ECDH_WRAPPED_KEY_SIZE 48 /* Forward declarations */ typedef struct pgp_fingerprint_t pgp_fingerprint_t; typedef struct pgp_ecdh_encrypted_t { pgp_mpi_t p; uint8_t m[ECDH_WRAPPED_KEY_SIZE]; size_t mlen; } pgp_ecdh_encrypted_t; rnp_result_t ecdh_validate_key(rnp::RNG *rng, const pgp_ec_key_t *key, bool secret); /* * @brief Sets hash algorithm and key wrapping algo * based on curve_id * * @param key ec key to set parameters for * @param curve underlying ECC curve ID * * @returns false if curve is not supported, otherwise true */ bool ecdh_set_params(pgp_ec_key_t *key, pgp_curve_t curve_id); /* * Encrypts session key with a KEK agreed during ECDH as specified in * RFC 4880 bis 01, 13.5 * * @param rng initialized rnp::RNG object * @param session_key key to be encrypted * @param session_key_len length of the key buffer * @param wrapped_key [out] resulting key wrapped in by some AES * as specified in RFC 3394 * @param wrapped_key_len [out] length of the `wrapped_key' buffer * Current implementation always produces 48 bytes as key * is padded with PKCS-5/7 * @param ephemeral_key [out] public ephemeral ECDH key used for key * agreement (private part). Must be initialized * @param pubkey public key to be used for encryption * @param fingerprint fingerprint of the pubkey * * @return RNP_SUCCESS on success and output parameters are populated * @return RNP_ERROR_NOT_SUPPORTED unknown curve * @return RNP_ERROR_BAD_PARAMETERS unexpected input provided * @return RNP_ERROR_SHORT_BUFFER `wrapped_key_len' to small to store result * @return RNP_ERROR_GENERIC implementation error */ rnp_result_t ecdh_encrypt_pkcs5(rnp::RNG * rng, pgp_ecdh_encrypted_t * out, const uint8_t *const in, size_t in_len, const pgp_ec_key_t * key, const pgp_fingerprint_t &fingerprint); /* * Decrypts session key with a KEK agreed during ECDH as specified in * RFC 4880 bis 01, 13.5 * * @param session_key [out] resulting session key * @param session_key_len [out] length of the resulting session key * @param wrapped_key session key wrapped with some AES as specified * in RFC 3394 * @param wrapped_key_len length of the `wrapped_key' buffer * @param ephemeral_key public ephemeral ECDH key coming from * encrypted packet. * @param seckey secret key to be used for decryption * @param fingerprint fingerprint of the key * * @return RNP_SUCCESS on success and output parameters are populated * @return RNP_ERROR_NOT_SUPPORTED unknown curve * @return RNP_ERROR_BAD_PARAMETERS unexpected input provided * @return RNP_ERROR_SHORT_BUFFER `session_key_len' to small to store result * @return RNP_ERROR_GENERIC decryption failed or implementation error */ rnp_result_t ecdh_decrypt_pkcs5(uint8_t * out, size_t * out_len, const pgp_ecdh_encrypted_t *in, const pgp_ec_key_t * key, const pgp_fingerprint_t & fingerprint); #endif // ECDH_H_