From 28e28e9ea9ef82981c5da5d941e20e6c3ffc827d Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 18 Apr 2016 12:35:32 +0200 Subject: [PATCH] Split symmetric/asymmetric encryption Change-Id: Iab1755771de9cdb8d2b2902cf6b6a1adcb343ade --- api/yaca/encrypt.h | 112 --------------------------------- api/yaca/seal.h | 150 ++++++++++++++++++++++++++++++++++++++++++++ examples/CMakeLists.txt | 1 + examples/encrypt.c | 122 ------------------------------------ examples/seal.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++ src/encrypt.c | 52 ---------------- src/seal.c | 83 +++++++++++++++++++++++++ 7 files changed, 396 insertions(+), 286 deletions(-) create mode 100644 api/yaca/seal.h create mode 100644 examples/seal.c create mode 100644 src/seal.c diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index e94fb37..8c52fc9 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -135,118 +135,6 @@ int yaca_decrypt_final(yaca_ctx_h ctx, char *plain, size_t *plain_len); -/**@}*/ - -/** - * @defgroup Advanced-Encryption-Asymmetric Advanced API for the asymmetric encryption. - * - * TODO: extended description and examples. - * - * TODO: Seal does more than just encrypt. It first generates the encryption key and IV, - * then encrypts whole message using this key (and selected symmetric algorithm). - * Finally it encrypts symmetric key with public key. - * - * @{ - */ - -/** - * @brief yaca_seal_init Initializes an asymmetric encryption context. - * - * @param[out] ctx Newly created context (must be freed with @see yaca_ctx_free). - * @param[in] pub_key Public key of the peer that will receive the encrypted data. - * @param[in] algo Symmetric algorithm that will be used. - * @param[in] bcm Block chaining mode for the symmetric algorithm. - * @param[out] sym_key Generated symmetric key that will be used. It is encrypted with peer's public key. - * @param[out] iv Generated initialization vector that will be used. - * - * @return 0 on success, negative on error (@see error.h). - */ -int yaca_seal_init(yaca_ctx_h *ctx, - const yaca_key_h pub_key, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - yaca_key_h *sym_key, - yaca_key_h *iv); - -/** - * @brief yaca_seal_update Encrypts piece of the data. - * - * @param[in,out] ctx Context created by @see yaca_seal_init. - * @param[in] plain Plain text to be encrypted. - * @param[in] plain_len Length of the plain text. - * @param[out] cipher Buffer for the encrypted data (must be allocated by client, @see yaca_get_output_length). - * @param[out] cipher_len Length of the encrypted data, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int yaca_seal_update(yaca_ctx_h ctx, - const char *plain, - size_t plain_len, - char *cipher, - size_t *cipher_len); - -/** - * @brief yaca_seal_final Encrypts the final piece of the data. - * - * @param[in,out] ctx A valid seal context. - * @param[out] cipher Final piece of the encrypted data (must be allocated by client, @see yaca_get_block_length). - * @param[out] cipher_len Length of the final piece, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int yaca_seal_final(yaca_ctx_h ctx, - char *cipher, - size_t *cipher_len); - -/** - * @brief yaca_open_init Initializes an asymmetric decryption context. - * - * @param[out] ctx Newly created context. Must be freed by @see yaca_ctx_free. - * @param[in] prv_key Private key, part of the pair that was used for the encryption. - * @param[in] algo Symmetric algorithm that was used for the encryption. - * @param[in] bcm Block chaining mode for the symmetric algorithm. - * @param[in] sym_key Symmetric key, encrypted with the public key, that was used to encrypt the data. - * @param[in] iv Initialization vector that was used for the encryption. - * - * @return 0 on success, negative on error (@see error.h). - */ -int yaca_open_init(yaca_ctx_h *ctx, - const yaca_key_h prv_key, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - const yaca_key_h sym_key, - const yaca_key_h iv); - -/** - * @brief yaca_open_update Decrypts piece of the data. - * - * @param[in,out] ctx Context created by @see yaca_open_init. - * @param[in] cipher Cipher text to be decrypted. - * @param[in] cipher_len Length of the cipher text. - * @param[out] plain Buffer for the decrypted data (must be allocated by client, @see yaca_get_output_length). - * @param[out] plain_len Length of the decrypted data, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int yaca_open_update(yaca_ctx_h ctx, - const char *cipher, - size_t cipher_len, - char *plain, - size_t *plain_len); - -/** - * @brief yaca_open_final Decrypts last chunk of sealed message. - * - * @param[in,out] ctx A valid open context. - * @param[out] plain Final piece of the decrypted data (must be allocated by client, @see yaca_get_block_length). - * @param[out] plain_len Length of the final piece, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int yaca_open_final(yaca_ctx_h ctx, - char *plain, - size_t *plain_len); - /** * @brief yaca_get_iv_bits Returns the recomended/default length of the IV for a given encryption configuration. * diff --git a/api/yaca/seal.h b/api/yaca/seal.h new file mode 100644 index 0000000..aa1a10b --- /dev/null +++ b/api/yaca/seal.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * 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 seal.h + * @brief + */ + +#ifndef SEAL_H +#define SEAL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Advanced-Encryption-Asymmetric Advanced API for the asymmetric encryption. + * + * TODO: extended description and examples. + * + * TODO: Seal does more than just encrypt. It first generates the encryption key and IV, + * then encrypts whole message using this key (and selected symmetric algorithm). + * Finally it encrypts symmetric key with public key. + * + * @{ + */ + +/** + * @brief yaca_seal_init Initializes an asymmetric encryption context. + * + * @param[out] ctx Newly created context (must be freed with @see yaca_ctx_free). + * @param[in] pub_key Public key of the peer that will receive the encrypted data. + * @param[in] algo Symmetric algorithm that will be used. + * @param[in] bcm Block chaining mode for the symmetric algorithm. + * @param[out] sym_key Generated symmetric key that will be used. It is encrypted with peer's public key. + * @param[out] iv Generated initialization vector that will be used. + * + * @return 0 on success, negative on error (@see error.h). + */ +int yaca_seal_init(yaca_ctx_h *ctx, + const yaca_key_h pub_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + yaca_key_h *sym_key, + yaca_key_h *iv); + +/** + * @brief yaca_seal_update Encrypts piece of the data. + * + * @param[in,out] ctx Context created by @see yaca_seal_init. + * @param[in] plain Plain text to be encrypted. + * @param[in] plain_len Length of the plain text. + * @param[out] cipher Buffer for the encrypted data (must be allocated by client, @see yaca_get_output_length). + * @param[out] cipher_len Length of the encrypted data, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int yaca_seal_update(yaca_ctx_h ctx, + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len); + +/** + * @brief yaca_seal_final Encrypts the final piece of the data. + * + * @param[in,out] ctx A valid seal context. + * @param[out] cipher Final piece of the encrypted data (must be allocated by client, @see yaca_get_block_length). + * @param[out] cipher_len Length of the final piece, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int yaca_seal_final(yaca_ctx_h ctx, + char *cipher, + size_t *cipher_len); + +/** + * @brief yaca_open_init Initializes an asymmetric decryption context. + * + * @param[out] ctx Newly created context. Must be freed by @see yaca_ctx_free. + * @param[in] prv_key Private key, part of the pair that was used for the encryption. + * @param[in] algo Symmetric algorithm that was used for the encryption. + * @param[in] bcm Block chaining mode for the symmetric algorithm. + * @param[in] sym_key Symmetric key, encrypted with the public key, that was used to encrypt the data. + * @param[in] iv Initialization vector that was used for the encryption. + * + * @return 0 on success, negative on error (@see error.h). + */ +int yaca_open_init(yaca_ctx_h *ctx, + const yaca_key_h prv_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + const yaca_key_h sym_key, + const yaca_key_h iv); + +/** + * @brief yaca_open_update Decrypts piece of the data. + * + * @param[in,out] ctx Context created by @see yaca_open_init. + * @param[in] cipher Cipher text to be decrypted. + * @param[in] cipher_len Length of the cipher text. + * @param[out] plain Buffer for the decrypted data (must be allocated by client, @see yaca_get_output_length). + * @param[out] plain_len Length of the decrypted data, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int yaca_open_update(yaca_ctx_h ctx, + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len); + +/** + * @brief yaca_open_final Decrypts last chunk of sealed message. + * + * @param[in,out] ctx A valid open context. + * @param[out] plain Final piece of the decrypted data (must be allocated by client, @see yaca_get_block_length). + * @param[out] plain_len Length of the final piece, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int yaca_open_final(yaca_ctx_h ctx, + char *plain, + size_t *plain_len); + +/**@}*/ + +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* SEAL_H */ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6413bad..cda1c9c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -51,6 +51,7 @@ ENDFUNCTION(BUILD_EXAMPLE) BUILD_EXAMPLE("yaca-example-digest" digest.c) BUILD_EXAMPLE("yaca-example-encrypt" encrypt.c) +BUILD_EXAMPLE("yaca-example-seal" seal.c) BUILD_EXAMPLE("yaca-example-encrypt-gcm" encrypt_aes_gcm.c) BUILD_EXAMPLE("yaca-example-sign" sign.c) BUILD_EXAMPLE("yaca-example-key-exchange" key_exchange.c) diff --git a/examples/encrypt.c b/examples/encrypt.c index f428713..eb8f3ce 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -228,126 +228,6 @@ ex_key: yaca_key_free(key); } -void encrypt_seal(void) -{ - int ret; - yaca_ctx_h ctx = YACA_CTX_NULL; - yaca_key_h key_pub = YACA_KEY_NULL; - yaca_key_h key_priv = YACA_KEY_NULL; - yaca_key_h aes_key = YACA_KEY_NULL; - yaca_key_h iv = YACA_KEY_NULL; - - char *enc = NULL; - char *dec = NULL; - size_t enc_size; - size_t dec_size; - - printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)4096, lorem1024); - - /// Generate key pair - ret = yaca_key_gen_pair(&key_priv, &key_pub, - YACA_KEY_TYPE_PAIR_RSA, - YACA_KEY_2048BIT); - if (ret) return; - - /// Encrypt a.k.a. seal - { - size_t out_size; - size_t rem; - - ret = yaca_seal_init(&ctx, key_pub, - YACA_ENC_AES, YACA_BCM_CBC, - &aes_key, &iv); - if (ret < 0) - goto ex_pk; - - ret = yaca_seal_update(ctx, lorem4096, 4096, NULL, &enc_size); - if (ret < 0) - goto ex_ak; - - ret = yaca_get_block_length(ctx); - if (ret < 0) - goto ex_ak; - - enc_size = enc_size + ret; - enc = yaca_malloc(enc_size); - if (enc == NULL) - goto ex_ak; - - // Seal and finalize - out_size = enc_size; - ret = yaca_seal_update(ctx, lorem4096, 4096, enc, &out_size); - if (ret < 0) - goto ex_of; - - rem = enc_size - out_size; - ret = yaca_seal_final(ctx, enc + out_size, &rem); - if (ret < 0) - goto ex_of; - - enc_size = rem + out_size; - - dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size); - - yaca_ctx_free(ctx); // TODO: perhaps it should not return value - } - - /// Decrypt a.k.a. open - { - size_t out_size; - size_t rem; - - ret = yaca_open_init(&ctx, key_priv, - YACA_ENC_AES, YACA_BCM_CBC, - aes_key, iv); - if (ret < 0) { - yaca_free(enc); - goto ex_ak; - } - - ret = yaca_open_update(ctx, enc, enc_size, NULL, &dec_size); - if (ret < 0) - goto ex_of; - - ret = yaca_get_block_length(ctx); - if (ret < 0) - goto ex_of; - - dec_size = dec_size + ret; - dec = yaca_malloc(dec_size); - if (dec == NULL) - goto ex_of; - - // Seal and finalize - out_size = enc_size; - ret = yaca_open_update(ctx, enc, enc_size, dec, &out_size); - if (ret < 0) - goto ex_in; - - rem = dec_size - out_size; - ret = yaca_open_final(ctx, dec + out_size, &rem); - if (ret < 0) - goto ex_in; - - dec_size = rem + out_size; - - printf("Decrypted data (16 of %zu bytes): %.16s\n", (size_t)dec_size, dec); - - yaca_ctx_free(ctx); // TODO: perhaps it should not return value - } - -ex_in: - yaca_free(dec); -ex_of: - yaca_free(enc); -ex_ak: - yaca_key_free(aes_key); - yaca_key_free(iv); -ex_pk: - yaca_key_free(key_pub); - yaca_key_free(key_priv); -} - int main() { int ret = yaca_init(); @@ -358,8 +238,6 @@ int main() encrypt_advanced(); - encrypt_seal(); - yaca_exit(); // TODO: what about handing of return value from exit?? return ret; } diff --git a/examples/seal.c b/examples/seal.c new file mode 100644 index 0000000..a96dfd0 --- /dev/null +++ b/examples/seal.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * 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 seal.c + * @brief + */ + +#include + +#include +#include +#include +#include "lorem.h" +#include "misc.h" + +void encrypt_seal(void) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + yaca_key_h key_pub = YACA_KEY_NULL; + yaca_key_h key_priv = YACA_KEY_NULL; + yaca_key_h aes_key = YACA_KEY_NULL; + yaca_key_h iv = YACA_KEY_NULL; + + char *enc = NULL; + char *dec = NULL; + size_t enc_size; + size_t dec_size; + + printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)4096, lorem1024); + + /// Generate key pair + ret = yaca_key_gen_pair(&key_priv, &key_pub, + YACA_KEY_TYPE_PAIR_RSA, + YACA_KEY_2048BIT); + if (ret) return; + + /// Encrypt a.k.a. seal + { + size_t out_size; + size_t rem; + + ret = yaca_seal_init(&ctx, key_pub, + YACA_ENC_AES, YACA_BCM_CBC, + &aes_key, &iv); + if (ret < 0) + goto ex_pk; + + ret = yaca_seal_update(ctx, lorem4096, 4096, NULL, &enc_size); + if (ret < 0) + goto ex_ak; + + ret = yaca_get_block_length(ctx); + if (ret < 0) + goto ex_ak; + + enc_size = enc_size + ret; + enc = yaca_malloc(enc_size); + if (enc == NULL) + goto ex_ak; + + // Seal and finalize + out_size = enc_size; + ret = yaca_seal_update(ctx, lorem4096, 4096, enc, &out_size); + if (ret < 0) + goto ex_of; + + rem = enc_size - out_size; + ret = yaca_seal_final(ctx, enc + out_size, &rem); + if (ret < 0) + goto ex_of; + + enc_size = rem + out_size; + + dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size); + + yaca_ctx_free(ctx); // TODO: perhaps it should not return value + } + + /// Decrypt a.k.a. open + { + size_t out_size; + size_t rem; + + ret = yaca_open_init(&ctx, key_priv, + YACA_ENC_AES, YACA_BCM_CBC, + aes_key, iv); + if (ret < 0) { + yaca_free(enc); + goto ex_ak; + } + + ret = yaca_open_update(ctx, enc, enc_size, NULL, &dec_size); + if (ret < 0) + goto ex_of; + + ret = yaca_get_block_length(ctx); + if (ret < 0) + goto ex_of; + + dec_size = dec_size + ret; + dec = yaca_malloc(dec_size); + if (dec == NULL) + goto ex_of; + + // Seal and finalize + out_size = enc_size; + ret = yaca_open_update(ctx, enc, enc_size, dec, &out_size); + if (ret < 0) + goto ex_in; + + rem = dec_size - out_size; + ret = yaca_open_final(ctx, dec + out_size, &rem); + if (ret < 0) + goto ex_in; + + dec_size = rem + out_size; + + printf("Decrypted data (16 of %zu bytes): %.16s\n", (size_t)dec_size, dec); + + yaca_ctx_free(ctx); // TODO: perhaps it should not return value + } + +ex_in: + yaca_free(dec); +ex_of: + yaca_free(enc); +ex_ak: + yaca_key_free(aes_key); + yaca_key_free(iv); +ex_pk: + yaca_key_free(key_pub); + yaca_key_free(key_priv); +} + +int main() +{ + int ret = yaca_init(); + if (ret < 0) + return ret; + + encrypt_seal(); + + yaca_exit(); // TODO: what about handing of return value from exit?? + return ret; +} diff --git a/src/encrypt.c b/src/encrypt.c index 24e9117..5aeecf7 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -399,55 +399,3 @@ API int yaca_decrypt_final(yaca_ctx_h ctx, return encrypt_final(ctx,(unsigned char*)plain, plain_len, OP_DECRYPT); } - -API int yaca_seal_init(yaca_ctx_h *ctx, - const yaca_key_h pub_key, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - yaca_key_h *sym_key, - yaca_key_h *iv) -{ - return YACA_ERROR_NOT_IMPLEMENTED; -} - -API int yaca_seal_update(yaca_ctx_h ctx, - const char *plain, - size_t plain_len, - char *cipher, - size_t *cipher_len) -{ - return YACA_ERROR_NOT_IMPLEMENTED; -} - -API int yaca_seal_final(yaca_ctx_h ctx, - char *cipher, - size_t *cipher_len) -{ - return YACA_ERROR_NOT_IMPLEMENTED; -} - -API int yaca_open_init(yaca_ctx_h *ctx, - const yaca_key_h prv_key, - yaca_enc_algo_e algo, - yaca_block_cipher_mode_e bcm, - const yaca_key_h sym_key, - const yaca_key_h iv) -{ - return YACA_ERROR_NOT_IMPLEMENTED; -} - -API int yaca_open_update(yaca_ctx_h ctx, - const char *cipher, - size_t cipher_len, - char *plain, - size_t *plain_len) -{ - return YACA_ERROR_NOT_IMPLEMENTED; -} - -API int yaca_open_final(yaca_ctx_h ctx, - char *plain, - size_t *plain_len) -{ - return YACA_ERROR_NOT_IMPLEMENTED; -} diff --git a/src/seal.c b/src/seal.c new file mode 100644 index 0000000..fb5b50e --- /dev/null +++ b/src/seal.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * 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 + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "internal.h" + +API int yaca_seal_init(yaca_ctx_h *ctx, + const yaca_key_h pub_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + yaca_key_h *sym_key, + yaca_key_h *iv) +{ + return YACA_ERROR_NOT_IMPLEMENTED; +} + +API int yaca_seal_update(yaca_ctx_h ctx, + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len) +{ + return YACA_ERROR_NOT_IMPLEMENTED; +} + +API int yaca_seal_final(yaca_ctx_h ctx, + char *cipher, + size_t *cipher_len) +{ + return YACA_ERROR_NOT_IMPLEMENTED; +} + +API int yaca_open_init(yaca_ctx_h *ctx, + const yaca_key_h prv_key, + yaca_enc_algo_e algo, + yaca_block_cipher_mode_e bcm, + const yaca_key_h sym_key, + const yaca_key_h iv) +{ + return YACA_ERROR_NOT_IMPLEMENTED; +} + +API int yaca_open_update(yaca_ctx_h ctx, + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len) +{ + return YACA_ERROR_NOT_IMPLEMENTED; +} + +API int yaca_open_final(yaca_ctx_h ctx, + char *plain, + size_t *plain_len) +{ + return YACA_ERROR_NOT_IMPLEMENTED; +} -- 2.7.4