From e80751b57c80355ace78a55d3327e4b948bb9822 Mon Sep 17 00:00:00 2001 From: sangsu Date: Wed, 25 May 2016 11:36:27 +0900 Subject: [PATCH 01/16] add @since_tizen 3.0 in yaca api header files Change-Id: I77736606ae86c6180e4eb0221610e03cc9abb9e5 Signed-off-by: sangsu --- api/yaca/crypto.h | 32 ++++++++++++++++++++++++ api/yaca/digest.h | 6 +++++ api/yaca/encrypt.h | 18 ++++++++++++-- api/yaca/error.h | 26 +++++++++++++------- api/yaca/key.h | 70 ++++++++++++++++++++++++++++++++--------------------- api/yaca/seal.h | 12 +++++++++ api/yaca/sign.h | 28 ++++++++++++++++----- api/yaca/simple.h | 22 ++++++++++++++--- api/yaca/types.h | 22 +++++++++++++++++ packaging/yaca.spec | 1 + src/CMakeLists.txt | 2 +- src/key.c | 0 12 files changed, 190 insertions(+), 49 deletions(-) mode change 100644 => 100755 api/yaca/error.h mode change 100644 => 100755 api/yaca/key.h mode change 100644 => 100755 src/key.c diff --git a/api/yaca/crypto.h b/api/yaca/crypto.h index 76a2897..5a44a9d 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/crypto.h @@ -41,12 +41,16 @@ extern "C" { /** * @brief NULL value for the crypto context. + * + * @since_tizen 3.0 */ #define YACA_CTX_NULL ((yaca_ctx_h) NULL) /** * @brief Initializes the library. Must be called before any other crypto function. * + * @since_tizen 3.0 + * * @return 0 on success, negative on error. * @see yaca_exit() */ @@ -55,6 +59,8 @@ int yaca_init(void); /** * @brief Closes the library. Must be called before exiting the application. * + * @since_tizen 3.0 + * * @see yaca_init() */ void yaca_exit(void); @@ -62,6 +68,8 @@ void yaca_exit(void); /** * @brief Allocates the memory. * + * @since_tizen 3.0 + * * @param[in] size Size of the allocation (bytes). * * @return NULL on failure, pointer to allocated memory otherwise. @@ -72,6 +80,8 @@ void *yaca_malloc(size_t size); /** * @brief Allocates the zeroed memory. * + * @since_tizen 3.0 + * * @param[in] size Size of the allocation (bytes). * * @return NULL on failure, pointer to allocated and zeroed memory otherwise. @@ -82,6 +92,8 @@ void *yaca_zalloc(size_t size); /** * @brief Re-allocates the memory. * + * @since_tizen 3.0 + * * @param[in] addr Address of the memory to be reallocated. * @param[in] size Size of the new allocation (bytes). * @@ -94,6 +106,8 @@ void *yaca_realloc(void *addr, size_t size); * @brief Frees the memory allocated by yaca_malloc(), yaca_zalloc(), * yaca_realloc() or one of the cryptographic operations. * + * @since_tizen 3.0 + * * @param[in] ptr Pointer to the memory to be freed. * @see yaca_malloc(), yaca_zalloc(), yaca_realloc() * @@ -103,6 +117,8 @@ void yaca_free(void *ptr); /** * @brief Generates random data. * + * @since_tizen 3.0 + * * @param[in,out] data Pointer to the memory to be randomized. * @param[in] data_len Length of the memory to be randomized. * @@ -114,6 +130,8 @@ int yaca_rand_bytes(char *data, size_t data_len); * @brief Sets the extended context parameters. Can only be called on an * initialized context. * + * @since_tizen 3.0 + * * @param[in,out] ctx Previously initialized crypto context. * @param[in] param Parameter to be set. * @param[in] value Parameter value. @@ -131,6 +149,8 @@ int yaca_ctx_set_param(yaca_ctx_h ctx, * @brief Returns the extended context parameters. Can only be called on an * initialized context. * + * @since_tizen 3.0 + * * @param[in] ctx Previously initialized crypto context. * @param[in] param Parameter to be read. * @param[out] value Copy of the parameter value (must be freed with yaca_free()). @@ -148,6 +168,8 @@ int yaca_ctx_get_param(const yaca_ctx_h ctx, * @brief Destroys the crypto context. Must be called on all contexts that are * no longer used. Passing YACA_CTX_NULL is allowed. * + * @since_tizen 3.0 + * * @param[in,out] ctx Crypto context. * @see #yaca_ctx_h * @@ -158,6 +180,8 @@ void yaca_ctx_free(yaca_ctx_h ctx); * @brief Returns the output length for a given algorithm. Can only be called * on an initialized context. * + * @since_tizen 3.0 + * * @param[in] ctx Previously initialized crypto context. * @param[in] input_len Length of the input data to be processed. * @param[in] output_len Required length of the output. @@ -168,22 +192,30 @@ int yaca_get_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *outpu /** * @brief Wrapper - returns the length of the digest (for a given context). + * + * @since_tizen 3.0 */ #define yaca_get_digest_length(ctxa, output_len) yaca_get_output_length((ctxa), 0, (output_len)) /** * @brief Wrapper - returns the length of the signature (for a given context). + * + * @since_tizen 3.0 */ #define yaca_get_sign_length(ctxa, output_len) yaca_get_output_length((ctxa), 0, (output_len)) /** * @brief Wrapper - returns the length of the block (for a given context). + * + * @since_tizen 3.0 */ #define yaca_get_block_length(ctxa, output_len) yaca_get_output_length((ctxa), 0, (output_len)) /** * @brief Safely compares first @b len bytes of two buffers. * + * @since_tizen 3.0 + * * @param[in] first Pointer to the first buffer. * @param[in] second Pointer to the second buffer. * @param[in] len Length to compare. diff --git a/api/yaca/digest.h b/api/yaca/digest.h index 5e3aa0d..1938360 100644 --- a/api/yaca/digest.h +++ b/api/yaca/digest.h @@ -42,6 +42,8 @@ extern "C" { /** * @brief Initializes a digest context. * + * @since_tizen 3.0 + * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. * @@ -53,6 +55,8 @@ int yaca_digest_init(yaca_ctx_h *ctx, yaca_digest_algo_e algo); /** * @brief Feeds the data into the message digest algorithm. * + * @since_tizen 3.0 + * * @param[in,out] ctx Context created by yaca_digest_init(). * @param[in] data Data from which the digest is to be calculated. * @param[in] data_len Length of the data. @@ -65,6 +69,8 @@ int yaca_digest_update(yaca_ctx_h ctx, const char *data, size_t data_len); /** * @brief Calculates the final digest. * + * @since_tizen 3.0 + * * @param[in,out] ctx A valid digest context. * @param[out] digest Buffer for the message digest (must be allocated by client, * see yaca_get_digest_length()). diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index 7e81d9b..cc07262 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -44,6 +44,8 @@ extern "C" { /** * @brief Initializes an encryption context. * + * @since_tizen 3.0 + * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption algorithm that will be used. * @param[in] bcm Chaining mode that will be used. @@ -62,6 +64,8 @@ int yaca_encrypt_init(yaca_ctx_h *ctx, /** * @brief Encrypts chunk of the data. * + * @since_tizen 3.0 + * * @param[in,out] ctx Context created by yaca_encrypt_init(). * @param[in] plain Plain text to be encrypted. * @param[in] plain_len Length of the plain text. @@ -81,6 +85,8 @@ int yaca_encrypt_update(yaca_ctx_h ctx, /** * @brief Encrypts the final chunk of the data. * + * @since_tizen 3.0 + * * @param[in,out] ctx A valid encrypt context. * @param[out] cipher Final piece of the encrypted data (must be allocated by client, see * yaca_get_block_length()). @@ -96,6 +102,8 @@ int yaca_encrypt_final(yaca_ctx_h ctx, /** * @brief Initializes an decryption context. * + * @since_tizen 3.0 + * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption algorithm that was used to encrypt the data. * @param[in] bcm Chaining mode that was used to encrypt the data. @@ -114,6 +122,8 @@ int yaca_decrypt_init(yaca_ctx_h *ctx, /** * @brief Decrypts chunk of the data. * + * @since_tizen 3.0 + * * @param[in,out] ctx Context created by yaca_decrypt_init(). * @param[in] cipher Cipher text to be decrypted. * @param[in] cipher_len Length of the cipher text. @@ -133,6 +143,8 @@ int yaca_decrypt_update(yaca_ctx_h ctx, /** * @brief Decrypts the final chunk of the data. * + * @since_tizen 3.0 + * * @param[in,out] ctx A valid decrypt context. * @param[out] plain Final piece of the decrypted data (must be allocated by client, see * yaca_get_block_length()). @@ -148,8 +160,10 @@ int yaca_decrypt_final(yaca_ctx_h ctx, /** * @brief Returns the recomended/default length of the IV for a given encryption configuration. * - * If returned iv_bits equals 0 that means that for this - * specific algorithm and its parameters IV is not used. + * @since_tizen 3.0 + * + * @remarks If returned iv_bits equals 0 that means that for this + * specific algorithm and its parameters IV is not used. * * @param[in] algo Encryption algorithm. * @param[in] bcm Chain mode. diff --git a/api/yaca/error.h b/api/yaca/error.h old mode 100644 new mode 100755 index 8aa150b..26f1979 --- a/api/yaca/error.h +++ b/api/yaca/error.h @@ -24,10 +24,15 @@ #ifndef YACA_ERROR_H #define YACA_ERROR_H +#include + #ifdef __cplusplus extern "C" { #endif + +#define TIZEN_ERROR_YACA -0x01E30000 + /** * @defgroup Error Yet another Crypto API - error enums. * @@ -35,17 +40,20 @@ extern "C" { */ /** - * @brief Error enums + * @brief Error enums + * + * @since_tizen 3.0 */ enum __yaca_error_code { - YACA_ERROR_NONE = 0, - YACA_ERROR_INVALID_ARGUMENT = -1, - YACA_ERROR_NOT_IMPLEMENTED = -2, - YACA_ERROR_INTERNAL = -3, - YACA_ERROR_TOO_BIG_ARGUMENT = -4, - YACA_ERROR_OUT_OF_MEMORY = -5, - YACA_ERROR_DATA_MISMATCH = -6, - YACA_ERROR_PASSWORD_INVALID = -7 + YACA_ERROR_NONE = TIZEN_ERROR_NONE, + YACA_ERROR_INVALID_ARGUMENT = TIZEN_ERROR_INVALID_PARAMETER, + + YACA_ERROR_NOT_IMPLEMENTED = TIZEN_ERROR_YACA | 0x01, + YACA_ERROR_INTERNAL = TIZEN_ERROR_YACA | 0x02, + YACA_ERROR_TOO_BIG_ARGUMENT = TIZEN_ERROR_YACA | 0x03, + YACA_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_YACA | 0x04, + YACA_ERROR_DATA_MISMATCH = TIZEN_ERROR_YACA | 0x05, + YACA_ERROR_PASSWORD_INVALID = TIZEN_ERROR_YACA | 0x06 }; /**@}*/ diff --git a/api/yaca/key.h b/api/yaca/key.h old mode 100644 new mode 100755 index e020171..e03834d --- a/api/yaca/key.h +++ b/api/yaca/key.h @@ -46,6 +46,8 @@ extern "C" { /** * @brief Get key's type. * + * @since_tizen 3.0 + * * @param[in] key Key which type we return. * @param[out] key_type Key type. * @@ -56,6 +58,8 @@ int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type); /** * @brief Get key's length (in bits). * + * @since_tizen 3.0 + * * @param[in] key Key which length we return. * @param[out] key_bits Key length in bits. * @@ -66,21 +70,23 @@ int yaca_key_get_bits(const yaca_key_h key, size_t *key_bits); /** * @brief Imports a key. * - * This function imports a key trying to match it to the key_type specified. - * It should autodetect both, key format and file format. + * @since_tizen 3.0 * - * For symmetric, IV and DES keys RAW binary format and BASE64 encoded - * binary format are supported. - * For asymmetric keys PEM and DER file formats are supported. + * @remarks This function imports a key trying to match it to the key_type specified. + * It should autodetect both, key format and file format. * - * Asymmetric keys can be in PKCS#1 or SSleay key formats (for RSA and - * DSA respectively). Asymmetric private keys can also be in PKCS#8 - * format. Additionally it is possible to import public RSA key from - * X509 certificate. + * For symmetric, IV and DES keys RAW binary format and BASE64 encoded + * binary format are supported. + * For asymmetric keys PEM and DER file formats are supported. * - * If the key is encrypted the algorithm will be autodetected and password - * used. If it's not known if the key is encrypted one should pass NULL as - * password and check for the YACA_ERROR_PASSWORD_INVALID return code. + * Asymmetric keys can be in PKCS#1 or SSleay key formats (for RSA and + * DSA respectively). Asymmetric private keys can also be in PKCS#8 + * format. Additionally it is possible to import public RSA key from + * X509 certificate. + * + * If the key is encrypted the algorithm will be autodetected and password + * used. If it's not known if the key is encrypted one should pass NULL as + * password and check for the YACA_ERROR_PASSWORD_INVALID return code. * * @param[out] key Returned key (must be freed with yaca_key_free()). * @param[in] key_type Type of the key. @@ -101,24 +107,26 @@ int yaca_key_import(yaca_key_h *key, /** * @brief Exports a key to arbitrary format. Export may fail if key is HW-based. * - * This function exports the key to an arbitrary key format and key file format. + * @since_tizen 3.0 + * + * @remarks This function exports the key to an arbitrary key format and key file format. * - * For key formats two values are allowed: - * - #YACA_KEY_FORMAT_DEFAULT: this is the only option possible in case of symmetric keys (or IV), - * for asymmetric keys it will choose PKCS#1 for RSA and SSLeay for DSA. - * - #YACA_KEY_FORMAT_PKCS8: this will only work for private asymmetric keys. + * For key formats two values are allowed: + * - #YACA_KEY_FORMAT_DEFAULT: this is the only option possible in case of symmetric keys (or IV), + * for asymmetric keys it will choose PKCS#1 for RSA and SSLeay for DSA. + * - #YACA_KEY_FORMAT_PKCS8: this will only work for private asymmetric keys. * - * The following file formats are supported: - * - #YACA_KEY_FILE_FORMAT_RAW: used only for symmetric, raw binary format - * - #YACA_KEY_FILE_FORMAT_BASE64: used only for symmetric, BASE64 encoded binary form - * - #YACA_KEY_FILE_FORMAT_PEM: used only for asymmetric, PEM file format - * - #YACA_KEY_FILE_FORMAT_DER: used only for asymmetric, DER file format + * The following file formats are supported: + * - #YACA_KEY_FILE_FORMAT_RAW: used only for symmetric, raw binary format + * - #YACA_KEY_FILE_FORMAT_BASE64: used only for symmetric, BASE64 encoded binary form + * - #YACA_KEY_FILE_FORMAT_PEM: used only for asymmetric, PEM file format + * - #YACA_KEY_FILE_FORMAT_DER: used only for asymmetric, DER file format * - * If no password is provided the exported key will be unencrypted. Only private - * RSA/DSA exported as PEM can be encrypted. + * If no password is provided the exported key will be unencrypted. Only private + * RSA/DSA exported as PEM can be encrypted. * - * TODO: document the default encryption algorithm (AES256 for FORMAT_DEFAULT, - * unknown yet for the FORMAT_PKCS8) + * TODO:document the default encryption algorithm (AES256 for FORMAT_DEFAULT, + * unknown yet for the FORMAT_PKCS8). * * @param[in] key Key to be exported. * @param[in] key_fmt Format of the key. @@ -141,7 +149,9 @@ int yaca_key_export(const yaca_key_h key, /** * @brief Generates a secure key (or an initialization vector). * - * This function is used to generate symmetric and private asymmetric keys. + * @since_tizen 3.0 + * + * @remarks This function is used to generate symmetric and private asymmetric keys. * * @param[out] key Newly generated key (must be freed with yaca_key_free()). * @param[in] key_type Type of the key to be generated. @@ -157,6 +167,8 @@ int yaca_key_gen(yaca_key_h *key, /** * @brief Extracts public key from a private one. * + * @since_tizen 3.0 + * * @param[in] prv_key Private key to extract the public one from. * @param[out] pub_key Extracted public key (must be freed with yaca_key_free()). * @@ -168,6 +180,8 @@ int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); /** * @brief Frees the key created by the library. Passing YACA_KEY_NULL is allowed. * + * @since_tizen 3.0 + * * @param key Key to be freed. * @see yaca_key_import(), yaca_key_export(), yaca_key_gen() * @@ -221,6 +235,8 @@ int yaca_key_derive_kea(const yaca_key_h prv_key, /** * @brief Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). * + * @since_tizen 3.0 + * * @param[in] password User password as a NULL-terminated string. * @param[in] salt Salt, should be non-zero. * @param[in] salt_len Length of the salt. diff --git a/api/yaca/seal.h b/api/yaca/seal.h index 4f7b2fa..bbf4ee7 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -46,6 +46,8 @@ extern "C" { /** * @brief Initializes an asymmetric encryption context. * + * @since_tizen 3.0 + * * @param[out] ctx Newly created context (must be freed with 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. @@ -68,6 +70,8 @@ int yaca_seal_init(yaca_ctx_h *ctx, /** * @brief Encrypts piece of the data. * + * @since_tizen 3.0 + * * @param[in,out] ctx Context created by yaca_seal_init(). * @param[in] plain Plain text to be encrypted. * @param[in] plain_len Length of the plain text. @@ -87,6 +91,8 @@ int yaca_seal_update(yaca_ctx_h ctx, /** * @brief Encrypts the final piece of the data. * + * @since_tizen 3.0 + * * @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()). @@ -102,6 +108,8 @@ int yaca_seal_final(yaca_ctx_h ctx, /** * @brief Initializes an asymmetric decryption context. * + * @since_tizen 3.0 + * * @param[out] ctx Newly created context. Must be freed by 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. @@ -124,6 +132,8 @@ int yaca_open_init(yaca_ctx_h *ctx, /** * @brief Decrypts piece of the data. * + * @since_tizen 3.0 + * * @param[in,out] ctx Context created by yaca_open_init(). * @param[in] cipher Cipher text to be decrypted. * @param[in] cipher_len Length of the cipher text. @@ -143,6 +153,8 @@ int yaca_open_update(yaca_ctx_h ctx, /** * @brief Decrypts last chunk of sealed message. * + * @since_tizen 3.0 + * * @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()). diff --git a/api/yaca/sign.h b/api/yaca/sign.h index beb5df2..36ba4dc 100644 --- a/api/yaca/sign.h +++ b/api/yaca/sign.h @@ -43,8 +43,10 @@ extern "C" { /** * @brief Initializes a signature context for asymmetric signatures. * - * For verification use yaca_verify_init(), yaca_verify_update() and - * yaca_verify_final() functions with matching public key. + * @since_tizen 3.0 + * + * @remarks For verification use yaca_verify_init(), yaca_verify_update() and + * yaca_verify_final() functions with matching public key. * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -66,8 +68,10 @@ int yaca_sign_init(yaca_ctx_h *ctx, /** * @brief Initializes a signature context for HMAC. * - * For verification, calculate message HMAC and compare with received MAC using - * yaca_memcmp(). + * @since_tizen 3.0 + * + * @remarks For verification, calculate message HMAC and compare with received MAC using + * yaca_memcmp(). * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. @@ -86,8 +90,10 @@ int yaca_sign_hmac_init(yaca_ctx_h *ctx, /** * @brief Initializes a signature context for CMAC. * - * For verification, calculate message CMAC and compare with received MAC using - * yaca_memcmp(). + * @since_tizen 3.0 + * + * @remarks For verification, calculate message CMAC and compare with received MAC using + * yaca_memcmp(). * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Encryption algorithm that will be used. @@ -106,6 +112,8 @@ int yaca_sign_cmac_init(yaca_ctx_h *ctx, /** * @brief Feeds the data into the digital signature or MAC algorithm. * + * @since_tizen 3.0 + * * @param[in,out] ctx Context created by yaca_sign_init(), * yaca_sign_hmac_init() or yaca_sign_cmac_init(). * @param[in] data Data to be signed. @@ -122,6 +130,8 @@ int yaca_sign_update(yaca_ctx_h ctx, /** * @brief Calculates the final signature or MAC. * + * @since_tizen 3.0 + * * @param[in,out] ctx A valid sign context. * @param[out] signature Buffer for the MAC or the signature, * (must be allocated by client, see yaca_get_sign_length()). @@ -139,6 +149,8 @@ int yaca_sign_final(yaca_ctx_h ctx, /** * @brief Initializes a signature verification context for asymmetric signatures * + * @since_tizen 3.0 + * * @param[out] ctx Newly created context (must be freed with yaca_ctx_free()). * @param[in] algo Digest algorithm that will be used. * @param[in] key Public key that will be used. Algorithm is deduced based on @@ -158,6 +170,8 @@ int yaca_verify_init(yaca_ctx_h *ctx, /** * @brief Feeds the data into the digital signature verification algorithm. * + * @since_tizen 3.0 + * * @param[in,out] ctx Context created by yaca_verify_init(). * @param[in] data Data to be verified. * @param[in] data_len Length of the data. @@ -172,6 +186,8 @@ int yaca_verify_update(yaca_ctx_h ctx, /** * @brief Performs the verification. * + * @since_tizen 3.0 + * * @param[in,out] ctx A valid verify context. * @param[in] signature Input signature (returned by yaca_sign_final()). * @param[in] signature_len Size of the signature. diff --git a/api/yaca/simple.h b/api/yaca/simple.h index c1d1d2b..b43a60b 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -50,6 +50,8 @@ extern "C" { /** * @brief Calculate a digest of a buffer. * + * @since_tizen 3.0 + * * @param[in] algo Digest algorithm (select #YACA_DIGEST_SHA256 if unsure). * @param[in] data Data from which the digest is to be calculated. * @param[in] data_len Length of the data. @@ -69,6 +71,8 @@ int yaca_digest_calc(yaca_digest_algo_e algo, /** * @brief Encrypt data using a symmetric cipher. * + * @since_tizen 3.0 + * * @param[in] algo Encryption algorithm (select #YACA_ENC_AES if unsure). * @param[in] bcm Chaining mode (select #YACA_BCM_CBC if unsure). * @param[in] sym_key Symmetric encryption key (see key.h for key generation functions). @@ -94,6 +98,8 @@ int yaca_encrypt(yaca_enc_algo_e algo, /** * @brief Decrypt data using a symmetric cipher. * + * @since_tizen 3.0 + * * @param[in] algo Decryption algorithm that was used to encrypt the data. * @param[in] bcm Chaining mode that was used to encrypt the data. * @param[in] sym_key Symmetric encryption key that was used to encrypt the data. @@ -119,6 +125,8 @@ int yaca_decrypt(yaca_enc_algo_e algo, /** * @brief Create a signature using asymmetric private key. * + * @since_tizen 3.0 + * * @param[in] algo Digest algorithm that will be used. * @param[in] key Private key that will be used. Algorithm is * deduced based on key type. Supported key types: @@ -144,6 +152,8 @@ int yaca_sign(yaca_digest_algo_e algo, /** * @brief Verify a signature using asymmetric public key. * + * @since_tizen 3.0 + * * @param[in] algo Digest algorithm that will be used. * @param[in] key Public key that will be used. Algorithm is * deduced based on key type. Supported key types: @@ -169,8 +179,10 @@ int yaca_verify(yaca_digest_algo_e algo, /** * @brief Calculate a HMAC of given message using symmetric key. * - * For verification, calculate message HMAC and compare with received MAC using - * yaca_memcmp(). + * @since_tizen 3.0 + * + * @remarks For verification, calculate message HMAC and compare with received MAC using + * yaca_memcmp(). * * @param[in] algo Digest algorithm that will be used. * @param[in] key Key that will be used. Supported key types: @@ -195,8 +207,10 @@ int yaca_hmac(yaca_digest_algo_e algo, /** * @brief Calculate a CMAC of given message using symmetric key. * - * For verification, calculate message CMAC and compare with received MAC using - * yaca_memcmp(). + * @since_tizen 3.0 + * + * @remarks For verification, calculate message CMAC and compare with received MAC using + * yaca_memcmp(). * * @param[in] algo Encryption algorithm that will be used. * @param[in] key Key that will be used. Supported key types: diff --git a/api/yaca/types.h b/api/yaca/types.h index 5a99113..7ba8cd7 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -38,16 +38,22 @@ extern "C" { /** * @brief Context + * + * @since_tizen 3.0 */ typedef struct yaca_ctx_s *yaca_ctx_h; /** * @brief Key + * + * @since_tizen 3.0 */ typedef struct yaca_key_s *yaca_key_h; /** * @brief Key formats + * + * @since_tizen 3.0 */ typedef enum { YACA_KEY_FORMAT_DEFAULT, /**< key is either PKCS#1 for RSA or SSLeay for DSA, also use this option for symmetric */ @@ -56,6 +62,8 @@ typedef enum { /** * @brief Key file formats + * + * @since_tizen 3.0 */ typedef enum { YACA_KEY_FILE_FORMAT_RAW, /**< key file is in raw binary format, used for symmetric keys */ @@ -66,6 +74,8 @@ typedef enum { /** * @brief Key types, IV is considered as key + * + * @since_tizen 3.0 */ typedef enum { YACA_KEY_TYPE_SYMMETRIC, /**< Generic symmetric cipher KEY */ @@ -88,6 +98,8 @@ typedef enum { /** * @brief Key length, It is possible to use arbitrary integer instead, this enums are placed here to avoid magic numbers. + * + * @since_tizen 3.0 */ typedef enum { YACA_KEY_IV_UNSAFE_24BIT = 24, /**< 24-bit IV */ @@ -113,6 +125,8 @@ typedef enum { /** * @brief Message digest algorithms. + * + * @since_tizen 3.0 */ typedef enum { YACA_DIGEST_MD5, /**< Message digest algorithm MD5 */ @@ -125,6 +139,8 @@ typedef enum { /** * @brief Symmetric encryption algorithms + * + * @since_tizen 3.0 */ typedef enum { /** @@ -230,6 +246,8 @@ typedef enum { /** * @brief Chaining modes for block ciphers + * + * @since_tizen 3.0 */ typedef enum { /** @@ -302,6 +320,8 @@ typedef enum { /** * @brief Non-standard parameters for algorithms + * + * @since_tizen 3.0 */ typedef enum { YACA_PARAM_PADDING, /**< Padding */ @@ -317,6 +337,8 @@ typedef enum { /** * @brief Paddings supported by Yet Another Crypto API + * + * @since_tizen 3.0 */ typedef enum { YACA_PADDING_NONE = 0, /**< total number of data MUST multiple of block size, Default */ diff --git a/packaging/yaca.spec b/packaging/yaca.spec index 126018c..327df37 100644 --- a/packaging/yaca.spec +++ b/packaging/yaca.spec @@ -6,6 +6,7 @@ License: Apache-2.0 Group: Security/Other Summary: Yet Another Crypto API BuildRequires: cmake +BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(openssl) Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d8369b..e21ca95 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,7 +45,7 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${_LIB_VERSION_}) ## Link libraries ############################################################## -PKG_CHECK_MODULES(YACA_DEPS REQUIRED openssl) +PKG_CHECK_MODULES(YACA_DEPS REQUIRED openssl capi-base-common) INCLUDE_DIRECTORIES(${API_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${YACA_DEPS_INCLUDE_DIRS}) diff --git a/src/key.c b/src/key.c old mode 100644 new mode 100755 -- 2.7.4 From 927c99596f36de494d4ed4e54cdda81e699b478d Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 18 May 2016 15:35:39 +0200 Subject: [PATCH 02/16] Simple API for signatures - implementation Change-Id: I0beab0dd414d2c12e08a262b5c2750acbc711763 --- src/simple.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/src/simple.c b/src/simple.c index 80414f8..3db1098 100644 --- a/src/simple.c +++ b/src/simple.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "internal.h" @@ -236,3 +237,121 @@ err: yaca_ctx_free(ctx); return ret; } + +static int sign(const yaca_ctx_h ctx, const char *data, size_t data_len, + char** signature, size_t* signature_len) +{ + int ret; + + assert(signature != NULL); + assert(signature_len != NULL); + + ret = yaca_sign_update(ctx, data, data_len); + if (ret != 0) + return ret; + + ret = yaca_get_sign_length(ctx, signature_len); + if (ret != 0) + return ret; + + *signature = yaca_malloc(*signature_len); + if (signature == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + ret = yaca_sign_final(ctx, *signature, signature_len); + if (ret != 0) { + yaca_free(*signature); + *signature = NULL; + } + + return ret; +} + +API int yaca_sign(yaca_digest_algo_e algo, + const yaca_key_h key, + const char *data, + size_t data_len, + char** signature, + size_t* signature_len) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + + ret = yaca_sign_init(&ctx, algo, key); + if (ret != 0) + return ret; + + ret = sign(ctx, data, data_len, signature, signature_len); + + yaca_ctx_free(ctx); + + return ret; +} + +API int yaca_verify(yaca_digest_algo_e algo, + const yaca_key_h key, + const char *data, + size_t data_len, + const char* signature, + size_t signature_len) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + + ret = yaca_verify_init(&ctx, algo, key); + if (ret != 0) + return ret; + + ret = yaca_verify_update(ctx, data, data_len); + if (ret != 0) + goto free_ctx; + + ret = yaca_verify_final(ctx, signature, signature_len); + +free_ctx: + yaca_ctx_free(ctx); + + return ret; +} + +API int yaca_hmac(yaca_digest_algo_e algo, + const yaca_key_h key, + const char *data, + size_t data_len, + char** mac, + size_t* mac_len) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + + ret = yaca_sign_hmac_init(&ctx, algo, key); + if (ret != 0) + return ret; + + ret = sign(ctx, data, data_len, mac, mac_len); + + yaca_ctx_free(ctx); + + return ret; +} + +API int yaca_cmac(yaca_enc_algo_e algo, + const yaca_key_h key, + const char *data, + size_t data_len, + char** mac, + size_t* mac_len) +{ + int ret; + yaca_ctx_h ctx = YACA_CTX_NULL; + + ret = yaca_sign_cmac_init(&ctx, algo, key); + if (ret != 0) + return ret; + + ret = sign(ctx, data, data_len, mac, mac_len); + + yaca_ctx_free(ctx); + + return ret; +} -- 2.7.4 From 20c2e824e1bd5475bea86350d8ad36337d2c06db Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 23 May 2016 10:47:53 +0200 Subject: [PATCH 03/16] Simple signature API example Change-Id: Iad04bc78c1d394bbf4c7f1e9215efb01ad365c65 --- examples/sign.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 145 insertions(+), 10 deletions(-) diff --git a/examples/sign.c b/examples/sign.c index c66e5d7..86ca1e2 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -26,11 +26,143 @@ #include #include #include +#include #include "lorem.h" #include "misc.h" #include "../src/debug.h" +// Signature creation and verification using simple API +void simple_sign_verify_asym(yaca_key_type_e type, const char *algo) +{ + char* signature = NULL; + size_t signature_len; + + yaca_key_h prv = YACA_KEY_NULL; + yaca_key_h pub = YACA_KEY_NULL; + + // GENERATE + if (yaca_key_gen(&prv, type, YACA_KEY_1024BIT) != 0) + return; + + if (yaca_key_extract_public(prv, &pub) != 0) + goto finish; + + // SIGN + if (yaca_sign(YACA_DIGEST_SHA512, + prv, + lorem4096, + LOREM4096_SIZE, + &signature, + &signature_len) != 0) + goto finish; + + dump_hex(signature, signature_len, "[Simple API] %s Signature of lorem4096:", algo); + + // VERIFY + if (yaca_verify(YACA_DIGEST_SHA512, + pub, + lorem4096, + LOREM4096_SIZE, + signature, + signature_len) != 0) + printf("[Simple API] %s verification failed\n", algo); + else + printf("[Simple API] %s verification succesful\n", algo); + +finish: + yaca_free(signature); + yaca_key_free(prv); + yaca_key_free(pub); +} + +void simple_sign_verify_hmac(void) +{ + char *signature1 = NULL; + char *signature2 = NULL; + size_t signature_len; + + yaca_key_h key = YACA_KEY_NULL; + + // GENERATE + if (yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT) != 0) + return; + + // SIGN + if (yaca_hmac(YACA_DIGEST_SHA512, + key, + lorem4096, + LOREM4096_SIZE, + &signature1, + &signature_len) != 0) + goto finish; + + dump_hex(signature1, signature_len, "[Simple API] HMAC Signature of lorem4096:"); + + // VERIFY + if (yaca_hmac(YACA_DIGEST_SHA512, + key, + lorem4096, + LOREM4096_SIZE, + &signature2, + &signature_len) != 0) + goto finish; + + if (yaca_memcmp(signature1, signature2, signature_len) != 0) + printf("[Simple API] HMAC verification failed\n"); + else + printf("[Simple API] HMAC verification succesful\n"); + +finish: + yaca_free(signature1); + yaca_free(signature2); + yaca_key_free(key); +} + +void simple_sign_verify_cmac(void) +{ + char *signature1 = NULL; + char *signature2 = NULL; + size_t signature_len; + + yaca_key_h key = YACA_KEY_NULL; + + // GENERATE + if (yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT)) + return; + + // SIGN + if (yaca_cmac(YACA_ENC_AES, + key, + lorem4096, + LOREM4096_SIZE, + &signature1, + &signature_len) != 0) + goto finish; + + dump_hex(signature1, signature_len, "[Simple API] CMAC Signature of lorem4096:"); + + + // VERIFY + if (yaca_cmac(YACA_ENC_AES, + key, + lorem4096, + LOREM4096_SIZE, + &signature2, + &signature_len) != 0) + goto finish; + + if (yaca_memcmp(signature1, signature2, signature_len) != 0) + printf("[Simple API] CMAC verification failed\n"); + else + printf("[Simple API] CMAC verification succesful\n"); + +finish: + yaca_free(signature1); + yaca_free(signature2); + yaca_key_free(key); +} + // Signature creation and verification using advanced API void sign_verify_asym(yaca_key_type_e type, const char *algo) { @@ -68,7 +200,7 @@ void sign_verify_asym(yaca_key_type_e type, const char *algo) if (yaca_sign_final(ctx, signature, &signature_len) != 0) goto finish; - dump_hex(signature, signature_len, "%s Signature of lorem4096:", algo); + dump_hex(signature, signature_len, "[Advanced API] %s Signature of lorem4096:", algo); // CLEANUP yaca_ctx_free(ctx); @@ -85,9 +217,9 @@ void sign_verify_asym(yaca_key_type_e type, const char *algo) goto finish; if (yaca_verify_final(ctx, signature, signature_len) != 0) - printf("%s verification failed\n", algo); + printf("[Advanced API] %s verification failed\n", algo); else - printf("%s verification succesful\n", algo); + printf("[Advanced API] %s verification succesful\n", algo); finish: yaca_free(signature); @@ -125,7 +257,7 @@ void sign_verify_hmac(void) if (yaca_sign_final(ctx, signature1, &signature_len) != 0) goto finish; - dump_hex(signature1, signature_len, "HMAC Signature of lorem4096:"); + dump_hex(signature1, signature_len, "[Advanced API] HMAC Signature of lorem4096:"); // CLEANUP yaca_ctx_free(ctx); @@ -148,9 +280,9 @@ void sign_verify_hmac(void) goto finish; if (yaca_memcmp(signature1, signature2, signature_len) != 0) - printf("HMAC verification failed\n"); + printf("[Advanced API] HMAC verification failed\n"); else - printf("HMAC verification succesful\n"); + printf("[Advanced API] HMAC verification succesful\n"); finish: yaca_free(signature1); @@ -188,7 +320,7 @@ void sign_verify_cmac(void) if (yaca_sign_final(ctx, signature1, &signature_len)) goto finish; - dump_hex(signature1, signature_len, "CMAC Signature of lorem4096:"); + dump_hex(signature1, signature_len, "[Advanced API] CMAC Signature of lorem4096:"); // CLEANUP yaca_ctx_free(ctx); @@ -211,9 +343,9 @@ void sign_verify_cmac(void) goto finish; if (yaca_memcmp(signature1, signature2, signature_len) != 0) - printf("CMAC verification failed\n"); + printf("[Advanced API] CMAC verification failed\n"); else - printf("CMAC verification succesful\n"); + printf("[Advanced API] CMAC verification succesful\n"); finish: yaca_free(signature1); @@ -230,7 +362,10 @@ int main() if (ret != 0) return ret; - // TODO simple? + simple_sign_verify_asym(YACA_KEY_TYPE_RSA_PRIV, "RSA"); + simple_sign_verify_asym(YACA_KEY_TYPE_DSA_PRIV, "DSA"); + simple_sign_verify_cmac(); + simple_sign_verify_hmac(); sign_verify_asym(YACA_KEY_TYPE_RSA_PRIV, "RSA"); sign_verify_asym(YACA_KEY_TYPE_DSA_PRIV, "DSA"); -- 2.7.4 From 3e4a2869b1e49f23551025d1b8b28dad8fd7d10e Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 23 May 2016 11:58:31 +0200 Subject: [PATCH 04/16] Fix code formatting in sign.c Change-Id: I767a1b32cf64ecae3f625c40c6ea83ec57368c37 --- src/sign.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/sign.c b/src/sign.c index 1a3a589..72f59b1 100644 --- a/src/sign.c +++ b/src/sign.c @@ -36,7 +36,7 @@ /* Operation type saved in context to recognize what * type of operation is performed and how to perform it. -*/ + */ enum sign_op_type { OP_SIGN = 0, OP_VERIFY = 1 @@ -64,7 +64,9 @@ static struct yaca_sign_ctx_s *get_sign_ctx(const yaca_ctx_h ctx) } } -static int get_sign_output_length(const yaca_ctx_h ctx, size_t input_len, size_t *output_len) +static int get_sign_output_length(const yaca_ctx_h ctx, + size_t input_len, + size_t *output_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); @@ -103,7 +105,10 @@ static void destroy_sign_context(yaca_ctx_h ctx) c->mdctx = NULL; } -int set_sign_param(yaca_ctx_h ctx, yaca_ex_param_e param, const void *value, size_t value_len) +int set_sign_param(yaca_ctx_h ctx, + yaca_ex_param_e param, + const void *value, + size_t value_len) { int ret; struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); @@ -162,7 +167,10 @@ int set_sign_param(yaca_ctx_h ctx, yaca_ex_param_e param, const void *value, siz return 0; } -int get_sign_param(const yaca_ctx_h ctx, yaca_ex_param_e param, void **value, size_t *value_len) +int get_sign_param(const yaca_ctx_h ctx, + yaca_ex_param_e param, + void **value, + size_t *value_len) { int ret; struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); @@ -227,8 +235,8 @@ int get_sign_param(const yaca_ctx_h ctx, yaca_ex_param_e param, void **value, si } API int yaca_sign_init(yaca_ctx_h *ctx, - yaca_digest_algo_e algo, - const yaca_key_h key) + yaca_digest_algo_e algo, + const yaca_key_h key) { struct yaca_sign_ctx_s *nc = NULL; const EVP_MD *md = NULL; @@ -300,7 +308,7 @@ API int yaca_sign_hmac_init(yaca_ctx_h *ctx, const struct yaca_key_simple_s *simple_key = key_get_simple(key); if (ctx == NULL || simple_key == NULL || - (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) + (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) return YACA_ERROR_INVALID_ARGUMENT; nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); @@ -364,7 +372,7 @@ API int yaca_sign_cmac_init(yaca_ctx_h *ctx, const struct yaca_key_simple_s *simple_key = key_get_simple(key); if (ctx == NULL || simple_key == NULL || - (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) + (key->type != YACA_KEY_TYPE_SYMMETRIC && key->type != YACA_KEY_TYPE_DES)) return YACA_ERROR_INVALID_ARGUMENT; nc = yaca_zalloc(sizeof(struct yaca_sign_ctx_s)); @@ -440,8 +448,8 @@ free_ctx: } API int yaca_sign_update(yaca_ctx_h ctx, - const char *data, - size_t data_len) + const char *data, + size_t data_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); int ret; @@ -461,8 +469,8 @@ API int yaca_sign_update(yaca_ctx_h ctx, } API int yaca_sign_final(yaca_ctx_h ctx, - char *signature, - size_t *signature_len) + char *signature, + size_t *signature_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); int ret; @@ -482,8 +490,8 @@ API int yaca_sign_final(yaca_ctx_h ctx, } API int yaca_verify_init(yaca_ctx_h *ctx, - yaca_digest_algo_e algo, - const yaca_key_h key) + yaca_digest_algo_e algo, + const yaca_key_h key) { struct yaca_sign_ctx_s *nc = NULL; const EVP_MD *md = NULL; @@ -544,8 +552,8 @@ free_ctx: } API int yaca_verify_update(yaca_ctx_h ctx, - const char *data, - size_t data_len) + const char *data, + size_t data_len) { struct yaca_sign_ctx_s *c = get_sign_ctx(ctx); int ret; -- 2.7.4 From d11c1e73386abe5843c196026ecf3e20c7e1f080 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 25 May 2016 17:52:09 +0200 Subject: [PATCH 05/16] Cleanup #include statements. Change-Id: I45d1600e7606915ac1408abe956e6b85d26bd5c9 --- examples/digest.c | 2 +- examples/encrypt.c | 1 + examples/key_exchange.c | 4 ++-- examples/key_import_export.c | 8 +++----- examples/misc.c | 3 ++- examples/seal.c | 1 + examples/sign.c | 1 + src/debug.c | 2 -- src/digest.c | 4 +--- src/encrypt.c | 3 --- src/internal.h | 1 + src/key.c | 11 ++++------- src/seal.c | 3 --- src/sign.c | 1 + src/simple.c | 4 ---- 15 files changed, 18 insertions(+), 31 deletions(-) diff --git a/examples/digest.c b/examples/digest.c index 9c68be3..76f0f12 100644 --- a/examples/digest.c +++ b/examples/digest.c @@ -21,11 +21,11 @@ * @brief */ -#include #include #include #include #include + #include "lorem.h" #include "misc.h" #include "../src/debug.h" diff --git a/examples/encrypt.c b/examples/encrypt.c index d436f52..ec2ee2f 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -28,6 +28,7 @@ #include #include #include + #include "lorem.h" #include "misc.h" #include "../src/debug.h" diff --git a/examples/key_exchange.c b/examples/key_exchange.c index 90c0cd3..559059e 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -22,11 +22,11 @@ */ #include + #include -#include #include -#include #include + #include "misc.h" #include "../src/debug.h" diff --git a/examples/key_import_export.c b/examples/key_import_export.c index 183068c..9c44266 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -23,15 +23,13 @@ #include -#include "misc.h" -#include "../src/debug.h" - #include -#include #include -#include #include +#include "misc.h" +#include "../src/debug.h" + int key_import_export_sym(yaca_key_h sym) { int ret; diff --git a/examples/misc.c b/examples/misc.c index 2a96106..892da72 100644 --- a/examples/misc.c +++ b/examples/misc.c @@ -25,9 +25,10 @@ #include #include +#include + #include -#include #include "misc.h" void dump_hex(const char *buf, size_t dump_size, const char *fmt, ...) diff --git a/examples/seal.c b/examples/seal.c index 2f47074..0811f43 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -27,6 +27,7 @@ #include #include #include + #include "lorem.h" #include "misc.h" #include "../src/debug.h" diff --git a/examples/sign.c b/examples/sign.c index 86ca1e2..fe56c51 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -22,6 +22,7 @@ */ #include + #include #include #include diff --git a/src/debug.c b/src/debug.c index b5f55bb..2cb0236 100644 --- a/src/debug.c +++ b/src/debug.c @@ -21,13 +21,11 @@ * @brief */ -#include #include #include #include -#include #include "internal.h" #include "debug.h" diff --git a/src/digest.c b/src/digest.c index 89eb1ff..28b095e 100644 --- a/src/digest.c +++ b/src/digest.c @@ -22,14 +22,12 @@ */ #include -#include #include -#include #include +#include #include -#include #include "internal.h" diff --git a/src/encrypt.c b/src/encrypt.c index b28c6be..f4749cd 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -22,11 +22,8 @@ */ #include -#include #include -#include -#include #include #include diff --git a/src/internal.h b/src/internal.h index 9a2a102..c010335 100644 --- a/src/internal.h +++ b/src/internal.h @@ -25,6 +25,7 @@ #define YACA_INTERNAL_H #include + #include #include diff --git a/src/key.c b/src/key.c index e3d5ffc..f31f34b 100755 --- a/src/key.c +++ b/src/key.c @@ -24,23 +24,20 @@ #include #include #include -#include #include #include -#include -#include -#include -#include - #include #include #include #include #include -#include "internal.h" +#include +#include +#include +#include "internal.h" int base64_decode_length(const char *data, size_t data_len, size_t *len) { diff --git a/src/seal.c b/src/seal.c index cbfe0ca..a3d3eb1 100644 --- a/src/seal.c +++ b/src/seal.c @@ -22,11 +22,8 @@ */ #include -#include #include -#include -#include #include #include diff --git a/src/sign.c b/src/sign.c index 72f59b1..4f749e8 100644 --- a/src/sign.c +++ b/src/sign.c @@ -29,6 +29,7 @@ #include #include +#include #include #include diff --git a/src/simple.c b/src/simple.c index 3db1098..2597c02 100644 --- a/src/simple.c +++ b/src/simple.c @@ -22,12 +22,8 @@ */ #include -#include #include -#include -#include - #include #include #include -- 2.7.4 From a889f4198a78493d4a4815733e15a05962c70536 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 27 May 2016 11:44:27 +0200 Subject: [PATCH 06/16] Remove some TODO's. Change-Id: Ic92d916f018078d1539132e0e44bd07de3e0d00c --- api/yaca/seal.h | 6 +++--- api/yaca/types.h | 1 - examples/digest.c | 2 +- examples/sign.c | 2 +- src/internal.h | 5 ++++- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/api/yaca/seal.h b/api/yaca/seal.h index bbf4ee7..2940f01 100644 --- a/api/yaca/seal.h +++ b/api/yaca/seal.h @@ -36,9 +36,9 @@ extern "C" { * * 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. + * @remarks 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. * * @{ */ diff --git a/api/yaca/types.h b/api/yaca/types.h index 7ba8cd7..0baf11c 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -92,7 +92,6 @@ typedef enum { YACA_KEY_TYPE_DH_PRIV, /**< Diffie-Hellman private key */ YACA_KEY_TYPE_EC_PUB, /**< Elliptic Curve public key (for DSA and DH) */ - YACA_KEY_TYPE_EC_PRIV, /**< Elliptic Curve private key (for DSA and DH) */ } yaca_key_type_e; diff --git a/examples/digest.c b/examples/digest.c index 76f0f12..9e01fc1 100644 --- a/examples/digest.c +++ b/examples/digest.c @@ -91,6 +91,6 @@ int main() digest_advanced(); - yaca_exit(); // TODO: what about handing of return value from exit?? + yaca_exit(); return ret; } diff --git a/examples/sign.c b/examples/sign.c index fe56c51..a6f4ee8 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -373,6 +373,6 @@ int main() sign_verify_hmac(); sign_verify_cmac(); - yaca_exit(); // TODO: what about handing of return value from exit?? + yaca_exit(); return ret; } diff --git a/src/internal.h b/src/internal.h index c010335..16b8b38 100644 --- a/src/internal.h +++ b/src/internal.h @@ -82,8 +82,11 @@ struct yaca_key_simple_s * - YACA_KEY_TYPE_RSA_PRIV * - YACA_KEY_TYPE_DSA_PUB * - YACA_KEY_TYPE_DSA_PRIV + * - YACA_KEY_TYPE_DH_PUB + * - YACA_KEY_TYPE_DH_PRIV + * - YACA_KEY_TYPE_EC_PUB + * - YACA_KEY_TYPE_EC_PRIV * - * TODO: and possibly others (for every key that uses EVP_PKEY) */ struct yaca_key_evp_s { -- 2.7.4 From 6774154ef5d67b88df0c16d46fe40f205694ccee Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 16 May 2016 14:54:35 +0200 Subject: [PATCH 07/16] Add support to AES GCM/CCM. Update documentation. Change-Id: Ifecf73fe15061afe8ad28a9ad20abc79f518f387 --- api/yaca/encrypt.h | 2 - api/yaca/simple.h | 2 +- api/yaca/types.h | 53 ++++++++++++++--- src/encrypt.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 194 insertions(+), 32 deletions(-) diff --git a/api/yaca/encrypt.h b/api/yaca/encrypt.h index cc07262..de7bc58 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/encrypt.h @@ -36,8 +36,6 @@ extern "C" { * * TODO: extended description and examples. * - * TODO: Let's describe how to set additional params (like GCM, CCM) - * * @{ */ diff --git a/api/yaca/simple.h b/api/yaca/simple.h index b43a60b..9c62314 100644 --- a/api/yaca/simple.h +++ b/api/yaca/simple.h @@ -39,7 +39,7 @@ extern "C" { * - All operations are single-shot (no streaming possible) * - Context is not used * - For now only digest and symmetric ciphers are supported - * - GCM chaining is not supported + * - GCM and CCM chaining is not supported * - All outputs are allocated by the library * * TODO: extended description and examples. diff --git a/api/yaca/types.h b/api/yaca/types.h index 0baf11c..70a097d 100644 --- a/api/yaca/types.h +++ b/api/yaca/types.h @@ -273,11 +273,27 @@ typedef enum { YACA_BCM_CBC, /** - * GCM block cipher mode, IV is needed. + * GCM block cipher mode. + * This is a variable IV length mode (recommended 96 bits IV). + * * Supported parameters: - * - #YACA_PARAM_GCM_TAG = GCM tag - * - #YACA_PARAM_GCM_TAG_LEN = GCM tag length - * - #YACA_PARAM_GCM_AAD = additional authentication data(optional) + * - #YACA_PARAM_GCM_TAG_LEN = GCM tag length\n + * Supported tag lengths: @c 32, @c 64, @c 96, @c 104, @c 112, @c 120, @c 128, + * (recommended 128 bits tag).\n + * Set after yaca_encrypt_final() and before yaca_ctx_get_param(#YACA_PARAM_GCM_TAG) + * in encryption operation.\n\n + * + * - #YACA_PARAM_GCM_TAG = GCM tag\n + * Get after yaca_encrypt_final() in encryption operation.\n + * Set before yaca_decrypt_final() in decryption operation.\n\n + * + * - #YACA_PARAM_GCM_AAD = additional authentication data (optional)\n + * Set after yaca_encrypt_init() and before yaca_encrypt_update() + * in encryption operation.\n + * Set after yaca_decrypt_init() and before yaca_decrypt_update() + * in decryption operation.\n\n + * + * @see examples/encrypt_aes_gcm_ccm.c */ YACA_BCM_GCM, @@ -307,10 +323,33 @@ typedef enum { /** * CBC-MAC Mode (AES). + * This is a variable IV length mode.\n + * Supported IV lengths: 56-104 bits in steps of 8 bits (recommended 56 bits IV).\n\n + * * Supported parameters: - * - #YACA_PARAM_CCM_TAG = CCM tag - * - #YACA_PARAM_CCM_TAG_LEN = CCM tag length - * - #YACA_PARAM_CCM_AAD = additional authentication data(optional) + * - #YACA_PARAM_CCM_TAG_LEN = CCM tag length\n + * Supported tag lengths: 32-128 bits in step of 16 bits (recommended 96 bits tag).\n + * Set after yaca_encrypt_init() and before yaca_encrypt_update() + * in encryption operation.\n\n + * + * - #YACA_PARAM_CCM_TAG = CCM tag\n + * Get after yaca_encrypt_final() in encryption operation.\n + * Set after yaca_decrypt_init() and before yaca_decrypt_update() + * in decryption operation.\n\n + * + * - #YACA_PARAM_CCM_AAD = additional authentication data (optional)\n + * The total plain text length must be passed to yaca_encrypt_update() + * if AAD is used.\n + * Set after yaca_encrypt_init() and before yaca_encrypt_update() + * in encryption operation.\n + * You can only call yaca_encrypt_update() once for AAD and once for the plain text.\n\n + * + * The total encrypted text length must be passed to yaca_decrypt_update() + * if AAD is used.\n + * Set after yaca_decrypt_init() and before yaca_decrypt_update() + * in decryption operation.\n\n + * + * @see examples/encrypt_aes_gcm_ccm.c */ YACA_BCM_CCM diff --git a/src/encrypt.c b/src/encrypt.c index f4749cd..c3d93ee 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -44,6 +44,7 @@ struct yaca_encrypt_ctx_s EVP_CIPHER_CTX *cipher_ctx; enum encrypt_op_type op_type; /* Operation context was created for */ + size_t tag_len; }; static struct yaca_encrypt_ctx_s *get_encrypt_ctx(const yaca_ctx_h ctx) @@ -76,8 +77,9 @@ static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len, siz struct yaca_encrypt_ctx_s *nc = get_encrypt_ctx(ctx); int block_size; - if (nc == NULL || nc->cipher_ctx == NULL) + if (nc == NULL) return YACA_ERROR_INVALID_ARGUMENT; + assert(nc->cipher_ctx != NULL); block_size = EVP_CIPHER_CTX_block_size(nc->cipher_ctx); if (block_size <= 0) { @@ -97,6 +99,107 @@ static int get_encrypt_output_length(const yaca_ctx_h ctx, size_t input_len, siz return 0; } +static int set_encrypt_param(yaca_ctx_h ctx, + yaca_ex_param_e param, + const void *value, + size_t value_len) +{ + struct yaca_encrypt_ctx_s *c = get_encrypt_ctx(ctx); + int len; + + if (c == NULL || value == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + assert(c->cipher_ctx != NULL); + + switch(param) + { + case YACA_PARAM_GCM_AAD: + case YACA_PARAM_CCM_AAD: + if (EVP_EncryptUpdate(c->cipher_ctx, NULL, &len, value, value_len) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + break; + case YACA_PARAM_GCM_TAG: + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_GCM_SET_TAG, + value_len, (void*)value) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + break; + case YACA_PARAM_GCM_TAG_LEN: + c->tag_len = *(int*)value; + break; + case YACA_PARAM_CCM_TAG: + // TODO Rebuild context + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_CCM_SET_TAG, + value_len, (void*)value) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + break; + case YACA_PARAM_CCM_TAG_LEN: + //TODO Rebuild context + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_CCM_SET_TAG, + value_len, NULL) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + c->tag_len = *(int*)value; + break; + default: + return YACA_ERROR_INVALID_ARGUMENT; + } + return 0; +} + +static int get_encrypt_param(const yaca_ctx_h ctx, + yaca_ex_param_e param, + void **value, + size_t *value_len) +{ + struct yaca_encrypt_ctx_s *c = get_encrypt_ctx(ctx); + + if (c == NULL || value == NULL || value_len == NULL) + return YACA_ERROR_INVALID_ARGUMENT; + assert(c->cipher_ctx != NULL); + + switch(param) + { + case YACA_PARAM_GCM_TAG: + if (c->tag_len == 0) + return YACA_ERROR_INVALID_ARGUMENT; + + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_GCM_GET_TAG, + c->tag_len, value) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + *value_len = c->tag_len; + break; + case YACA_PARAM_CCM_TAG: + if (c->tag_len == 0) + return YACA_ERROR_INVALID_ARGUMENT; + + if (EVP_CIPHER_CTX_ctrl(c->cipher_ctx, + EVP_CTRL_CCM_GET_TAG, + c->tag_len, value) != 1) { + ERROR_DUMP(YACA_ERROR_INTERNAL); + return YACA_ERROR_INTERNAL; + } + *value_len = c->tag_len; + break; + default: + return YACA_ERROR_INVALID_ARGUMENT; + break; + } + return 0; +} + static const char *encrypt_algo_to_str(yaca_enc_algo_e algo) { switch(algo) @@ -240,7 +343,10 @@ static int encrypt_init(yaca_ctx_h *ctx, nc->ctx.type = YACA_CTX_ENCRYPT; nc->ctx.ctx_destroy = destroy_encrypt_ctx; nc->ctx.get_output_length = get_encrypt_output_length; + nc->ctx.set_param = set_encrypt_param; + nc->ctx.get_param = get_encrypt_param; nc->op_type = op_type; + nc->tag_len = 0; ret = yaca_key_get_bits(sym_key, &key_bits); if (ret != 0) @@ -274,7 +380,10 @@ static int encrypt_init(yaca_ctx_h *ctx, ret = YACA_ERROR_INVALID_ARGUMENT; goto err_free; } - if (iv_bits != iv_bits_check) { /* IV length doesn't match cipher */ + /* IV length doesn't match cipher (GCM & CCM supports variable IV length) */ + if (iv_bits != iv_bits_check && + bcm != YACA_BCM_GCM && + bcm != YACA_BCM_CCM) { ret = YACA_ERROR_INVALID_ARGUMENT; goto err_free; } @@ -291,39 +400,56 @@ static int encrypt_init(yaca_ctx_h *ctx, switch (op_type) { case OP_ENCRYPT: ret = EVP_EncryptInit_ex(nc->cipher_ctx, cipher, NULL, NULL, NULL); - if (ret != 1) - break; + break; + case OP_DECRYPT: + ret = EVP_DecryptInit_ex(nc->cipher_ctx, cipher, NULL, NULL, NULL); + break; + default: + ret = YACA_ERROR_INVALID_ARGUMENT; + goto err_ctx; + } + + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto err_ctx; + } + + /* Handling of algorithms with variable key length */ + ret = EVP_CIPHER_CTX_set_key_length(nc->cipher_ctx, key_bits / 8); + if (ret != 1) { + ret = YACA_ERROR_INVALID_ARGUMENT; + ERROR_DUMP(ret); + goto err_ctx; + } + + /* Handling of algorithms with variable IV length */ + if (iv_bits != iv_bits_check) { + if (bcm == YACA_BCM_GCM) + ret = EVP_CIPHER_CTX_ctrl(nc->cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, + iv_bits_check / 8, NULL); + + if (bcm == YACA_BCM_CCM) + ret = EVP_CIPHER_CTX_ctrl(nc->cipher_ctx, EVP_CTRL_CCM_SET_IVLEN, + iv_bits_check / 8, NULL); - /* Handling of algorithms with variable key length */ - ret = EVP_CIPHER_CTX_set_key_length(nc->cipher_ctx, key_bits / 8); if (ret != 1) { ret = YACA_ERROR_INVALID_ARGUMENT; ERROR_DUMP(ret); goto err_ctx; } + } + switch (op_type) { + case OP_ENCRYPT: ret = EVP_EncryptInit_ex(nc->cipher_ctx, NULL, NULL, (unsigned char*)lkey->d, iv_data); - break; case OP_DECRYPT: - ret = EVP_DecryptInit_ex(nc->cipher_ctx, cipher, NULL, NULL, NULL); - if (ret != 1) - break; - - /* Handling of algorithms with variable key length */ - ret = EVP_CIPHER_CTX_set_key_length(nc->cipher_ctx, key_bits / 8); - if (ret != 1) { - ret = YACA_ERROR_INVALID_ARGUMENT; - ERROR_DUMP(ret); - goto err_ctx; - } - ret = EVP_DecryptInit_ex(nc->cipher_ctx, NULL, NULL, (unsigned char*)lkey->d, iv_data); - break; default: ret = YACA_ERROR_INVALID_ARGUMENT; @@ -357,8 +483,7 @@ static int encrypt_update(yaca_ctx_h ctx, int ret; int loutput_len; - if (c == NULL || input == NULL || input_len == 0 || - output == NULL || output_len == NULL || op_type != c->op_type) + if (c == NULL || input_len == 0 || output_len == NULL || op_type != c->op_type) return YACA_ERROR_INVALID_ARGUMENT; loutput_len = *output_len; -- 2.7.4 From ae2000db6be9a0d69aeba3240082a36e71cadd14 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 13 May 2016 12:54:13 +0200 Subject: [PATCH 08/16] Rework AES GCM example. Change-Id: I7c068de59f18496a34a7a7a31f5258e34445764d --- examples/encrypt_aes_gcm.c | 138 +++++++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 73 deletions(-) diff --git a/examples/encrypt_aes_gcm.c b/examples/encrypt_aes_gcm.c index c89127e..7fc0fa0 100644 --- a/examples/encrypt_aes_gcm.c +++ b/examples/encrypt_aes_gcm.c @@ -33,148 +33,140 @@ #include "misc.h" #include "../src/debug.h" -// Symmetric aes gcm encryption using advanced API void encrypt_decrypt_aes_gcm(void) { - int ret; + yaca_enc_algo_e algo = YACA_ENC_AES; + yaca_block_cipher_mode_e bcm = YACA_BCM_GCM; + yaca_key_type_e key_type = YACA_KEY_TYPE_SYMMETRIC; + size_t key_bits = YACA_KEY_256BIT; + size_t iv_bits = YACA_KEY_IV_128BIT; yaca_ctx_h ctx = YACA_CTX_NULL; - yaca_key_h key = YACA_KEY_NULL; yaca_key_h iv = YACA_KEY_NULL; - yaca_key_h aad_key = YACA_KEY_NULL; // add YACA_YACA_KEY_TYPE_AAD ? - char *plaintext = NULL; - char *ciphertext = NULL; + char *enc = NULL; + char *dec = NULL; + size_t enc_size; + size_t dec_size; + char *aad = NULL; char *tag = NULL; - size_t plaintext_len; - size_t ciphertext_len; - size_t aad_len; - size_t tag_len; + size_t aad_size = 16; + size_t tag_size = 16; + + size_t block_len; + size_t output_len; + size_t out_size; + size_t rem; printf("Plain data (16 of %zu bytes): %.16s\n", LOREM4096_SIZE, lorem4096); - /// Key generation + /* Key generation */ + if (yaca_key_gen(&key, key_type, key_bits) != 0) + return; - ret = yaca_key_gen(&key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_256BIT); // key_type, key_len, *key ? looks imo much better - if (ret != 0) + /* IV generation */ + if (yaca_key_gen(&iv, YACA_KEY_TYPE_IV, iv_bits) != 0) goto clean; - // use YACA_KEY_IV_128BIT & YACA_KEY_TYPE_IV or maybe YACA_KEY_128BIT & YACA_KEY_TYPE_SYMMETRIC ? - ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, YACA_KEY_IV_128BIT); - if (ret != 0) + if ((aad = yaca_zalloc(aad_size)) == NULL) goto clean; - // use YACA_KEY_128BIT & YACA_KEY_TYPE_SYMMETRIC or maybe add YACA_KEY_AAD_128BIT & YACA_KEY_TYPE_AAD ? - ret = yaca_key_gen(&aad_key, YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_UNSAFE_128BIT); - if (ret != 0) + if (yaca_rand_bytes(aad, aad_size) != 0) goto clean; - // generate and export aad? - ret = yaca_key_export(aad_key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_RAW, NULL, &aad, &aad_len); - if (ret != 0) + if ((tag = yaca_zalloc(tag_size)) == NULL) goto clean; - /// Encryption + /* Encryption */ { - size_t len; + if (yaca_encrypt_init(&ctx, algo, bcm, key, iv) != 0) + goto clean; - ret = yaca_encrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_GCM, key, iv); - if (ret != 0) + /* Provide any AAD data */ + if (yaca_ctx_set_param(ctx, YACA_PARAM_GCM_AAD, aad, aad_size) != 0) goto clean; - ret = yaca_ctx_set_param(ctx, YACA_PARAM_GCM_AAD, aad, aad_len); - if (ret != 0) + if (yaca_get_block_length(ctx, &block_len) != 0) goto clean; - ret = yaca_get_output_length(ctx, LOREM4096_SIZE, &ciphertext_len); - if (ret != 0) + if (yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len) != 0) goto clean; - ret = yaca_get_block_length(ctx, &len); - if (ret != 0) + /* Calculate max output: size of update + final chunks */ + enc_size = output_len + block_len; + if ((enc = yaca_malloc(enc_size)) == NULL) goto clean; - ciphertext_len += len ; // Add block size for finalize - ciphertext = yaca_malloc(ciphertext_len); - if (ciphertext == NULL) + out_size = enc_size; + if (yaca_encrypt_update(ctx, lorem4096, LOREM4096_SIZE, enc, &out_size) != 0) goto clean; - ret = yaca_encrypt_update(ctx, lorem4096, LOREM4096_SIZE, ciphertext, &len); - if (ret != 0) + rem = enc_size - out_size; + if (yaca_encrypt_final(ctx, enc + out_size, &rem) != 0) goto clean; - ciphertext_len = len; + enc_size = rem + out_size; - ret = yaca_encrypt_final(ctx, ciphertext + len, &len); - if (ret != 0) + /* Set the tag length and get the tag after final encryption */ + if (yaca_ctx_set_param(ctx, YACA_PARAM_GCM_TAG_LEN, + (void*)&tag_size, sizeof(tag_size)) != 0) goto clean; - ciphertext_len += len; - - ret = yaca_ctx_get_param(ctx, YACA_PARAM_GCM_TAG, (void*)&tag, &tag_len); - if (ret != 0) + if (yaca_ctx_get_param(ctx, YACA_PARAM_GCM_TAG, (void**)tag, &tag_size) != 0) goto clean; - dump_hex(ciphertext, 16, "Encrypted data (16 of %zu bytes): ", ciphertext_len); + dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size); yaca_ctx_free(ctx); + ctx = YACA_CTX_NULL; } - /// Decryption + /* Decryption */ { - size_t len; - - ret = yaca_decrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_GCM, key, iv); - if (ret != 0) + if (yaca_decrypt_init(&ctx, algo, bcm, key, iv) != 0) goto clean; - ret = yaca_ctx_set_param(ctx, YACA_PARAM_GCM_AAD, aad, aad_len); - if (ret != 0) + /* Provide any AAD data */ + if (yaca_ctx_set_param(ctx, YACA_PARAM_GCM_AAD, aad, aad_size) != 0) goto clean; - ret = yaca_get_output_length(ctx, ciphertext_len, &plaintext_len); - if (ret != 0) + if (yaca_get_block_length(ctx, &block_len) != 0) goto clean; - ret = yaca_get_block_length(ctx, &len); - if (ret != 0) + if (yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len) != 0) goto clean; - plaintext_len += len; // Add block size for finalize - plaintext = yaca_malloc(plaintext_len); - if (plaintext == NULL) + /* Calculate max output: size of update + final chunks */ + dec_size = output_len + block_len; + if ((dec = yaca_malloc(dec_size)) == NULL) goto clean; - ret = yaca_decrypt_update(ctx, ciphertext, ciphertext_len, plaintext, &len); - if (ret != 0) + out_size = dec_size; + if (yaca_decrypt_update(ctx, enc, enc_size, dec, &out_size) != 0) goto clean; - plaintext_len = len; + rem = dec_size - out_size; - ret = yaca_ctx_set_param(ctx, YACA_PARAM_GCM_TAG, tag, tag_len); - if (ret != 0) + /* Set expected tag value before final decryption */ + if (yaca_ctx_set_param(ctx, YACA_PARAM_GCM_TAG, tag, tag_size) != 0) goto clean; - ret = yaca_encrypt_final(ctx, plaintext + len, &len); - if (ret != 0) + if (yaca_decrypt_final(ctx, dec + out_size, &rem) != 0) goto clean; - plaintext_len += len; - - printf("Decrypted data (16 of %zu bytes): %.16s\n", plaintext_len, plaintext); + dec_size = rem + out_size; - yaca_ctx_free(ctx); + printf("Decrypted data (16 of %zu bytes): %.16s\n\n", dec_size, dec); } clean: - yaca_free(plaintext); - yaca_free(ciphertext); + yaca_free(enc); + yaca_free(dec); yaca_free(tag); yaca_free(aad); yaca_ctx_free(ctx); - yaca_key_free(aad_key); yaca_key_free(iv); yaca_key_free(key); } -- 2.7.4 From 0b4813725dbc4abd95cd8da7c00f4c9ffdd3e14c Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 20 May 2016 12:22:30 +0200 Subject: [PATCH 09/16] Add AES CCM example. Change-Id: I1dbb4d481f6ab0c1b373698ae1d6b827b9b6ab82 --- examples/CMakeLists.txt | 14 +- .../{encrypt_aes_gcm.c => encrypt_aes_gcm_ccm.c} | 149 ++++++++++++++++++++- 2 files changed, 154 insertions(+), 9 deletions(-) rename examples/{encrypt_aes_gcm.c => encrypt_aes_gcm_ccm.c} (53%) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c8461ec..4cf4681 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -43,13 +43,13 @@ FUNCTION(BUILD_EXAMPLE EXAMPLE_NAME SOURCE_FILE) DESTINATION ${EXAMPLES_DIR}) 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) -BUILD_EXAMPLE("yaca-example-key-impexp" key_import_export.c) +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-ccm" encrypt_aes_gcm_ccm.c) +BUILD_EXAMPLE("yaca-example-sign" sign.c) +BUILD_EXAMPLE("yaca-example-key-exchange" key_exchange.c) +BUILD_EXAMPLE("yaca-example-key-impexp" key_import_export.c) INSTALL(FILES ${COMMON_SOURCES} DESTINATION ${EXAMPLES_DIR}) diff --git a/examples/encrypt_aes_gcm.c b/examples/encrypt_aes_gcm_ccm.c similarity index 53% rename from examples/encrypt_aes_gcm.c rename to examples/encrypt_aes_gcm_ccm.c index 7fc0fa0..4ae8ff6 100644 --- a/examples/encrypt_aes_gcm.c +++ b/examples/encrypt_aes_gcm_ccm.c @@ -17,7 +17,7 @@ */ /** - * @file encrypt_aes_gcm.c + * @file encrypt_aes_gcm_ccm.c * @brief */ @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "lorem.h" @@ -60,6 +59,7 @@ void encrypt_decrypt_aes_gcm(void) size_t out_size; size_t rem; + printf("AES GCM 256bit key encryption/decryption\n"); printf("Plain data (16 of %zu bytes): %.16s\n", LOREM4096_SIZE, lorem4096); /* Key generation */ @@ -171,6 +171,150 @@ clean: yaca_key_free(key); } +void encrypt_decrypt_aes_ccm(void) +{ + yaca_enc_algo_e algo = YACA_ENC_AES; + yaca_block_cipher_mode_e bcm = YACA_BCM_CCM; + yaca_key_type_e key_type = YACA_KEY_TYPE_SYMMETRIC; + size_t key_bits = YACA_KEY_256BIT; + size_t iv_bits = YACA_KEY_IV_64BIT; + + yaca_ctx_h ctx = YACA_CTX_NULL; + yaca_key_h 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; + + char *aad = NULL; + char *tag = NULL; + size_t aad_size = 16; + size_t tag_size = 12; + + size_t block_len; + size_t output_len; + size_t out_size; + size_t rem; + size_t len; + + printf("AES CCM 256bit key encryption/decryption\n"); + printf("Plain data (16 of %zu bytes): %.16s\n", LOREM4096_SIZE, lorem4096); + + /* Key generation */ + if (yaca_key_gen(&key, key_type, key_bits) != 0) + return; + + /* IV generation */ + if (yaca_key_gen(&iv, YACA_KEY_TYPE_IV, iv_bits) != 0) + goto clean; + + if ((aad = yaca_zalloc(aad_size)) == NULL) + goto clean; + + if (yaca_rand_bytes(aad, aad_size) != 0) + goto clean; + + if ((tag = yaca_zalloc(tag_size)) == NULL) + goto clean; + + /* Encryption */ + { + if (yaca_encrypt_init(&ctx, algo, bcm, key, iv) != 0) + goto clean; + + /* Set tag length (optionally) */ + if (yaca_ctx_set_param(ctx, YACA_PARAM_CCM_TAG_LEN, + (void*)&tag_size, sizeof(tag_size)) != 0) + goto clean; + + /* The total plain text length must be passed (only needed if AAD is passed) */ + if (yaca_encrypt_update(ctx, NULL, LOREM4096_SIZE , NULL, &len) != 0) + goto clean; + + if (yaca_ctx_set_param(ctx, YACA_PARAM_CCM_AAD, aad, aad_size) != 0) + goto clean; + + if (yaca_get_block_length(ctx, &block_len) != 0) + goto clean; + + if (yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len) != 0) + goto clean; + + /* Calculate max output: size of update + final chunks */ + enc_size = output_len + block_len; + if ((enc = yaca_malloc(enc_size)) == NULL) + goto clean; + + out_size = enc_size; + if (yaca_encrypt_update(ctx, lorem4096, LOREM4096_SIZE, enc, &out_size) != 0) + goto clean; + + rem = enc_size - out_size; + if (yaca_encrypt_final(ctx, enc + out_size, &rem) != 0) + goto clean; + + enc_size = rem + out_size; + + /* Get the tag after final encryption */ + if (yaca_ctx_get_param(ctx, YACA_PARAM_CCM_TAG, (void**)tag, &tag_size) != 0) + goto clean; + + dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size); + + yaca_ctx_free(ctx); + ctx = YACA_CTX_NULL; + } + + /* Decryption */ + { + if (yaca_decrypt_init(&ctx, algo, bcm, key, iv) != 0) + goto clean; + + /* Set expected tag value */ + if (yaca_ctx_set_param(ctx, YACA_PARAM_CCM_TAG, tag, tag_size) != 0) + goto clean; + + /* The total encrypted text length must be passed (only needed if AAD is passed) */ + if (yaca_decrypt_update(ctx, NULL, enc_size , NULL, &len) != 0) + goto clean; + + if (yaca_ctx_set_param(ctx, YACA_PARAM_CCM_AAD, aad, aad_size) != 0) + goto clean; + + if (yaca_get_block_length(ctx, &block_len) != 0) + goto clean; + + if (yaca_get_output_length(ctx, LOREM4096_SIZE, &output_len) != 0) + goto clean; + + /* Calculate max output: size of update + final chunks */ + dec_size = output_len + block_len; + if ((dec = yaca_malloc(dec_size)) == NULL) + goto clean; + + out_size = dec_size; + /* The tag verify is performed when you call the final yaca_decrypt_update(), + * there is no call to yaca_decrypt_final() */ + if (yaca_decrypt_update(ctx, enc, enc_size, dec, &out_size) != 0) + goto clean; + + dec_size = out_size; + + printf("Decrypted data (16 of %zu bytes): %.16s\n\n", dec_size, dec); + } + +clean: + yaca_free(enc); + yaca_free(dec); + yaca_free(tag); + yaca_free(aad); + yaca_ctx_free(ctx); + yaca_key_free(iv); + yaca_key_free(key); +} + int main() { yaca_debug_set_error_cb(debug_func); @@ -180,6 +324,7 @@ int main() return ret; encrypt_decrypt_aes_gcm(); + encrypt_decrypt_aes_ccm(); yaca_exit(); return ret; -- 2.7.4 From 8bb682b3b03fcba38080cc192d4b9cfdff28b514 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 25 May 2016 13:32:42 +0200 Subject: [PATCH 10/16] Add emacs support file to git ignore Change-Id: I4034f227914f8ebcda4c2cb79d4da722f804a8ab --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3a844ae..5bfc1a9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ doc/man GPATH GRTAGS GTAGS +.dir-locals.el -- 2.7.4 From fda5cba6f2d3aad79d8d8c1b875c36ed4116f2df Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 18 May 2016 14:06:55 +0200 Subject: [PATCH 11/16] read_stdin_line() - misc function in examples Useful e.g. to read passwords for the purpose of examples. Change-Id: I75ba71667625ca9ffeae5ee288ac3b5c74053879 --- examples/misc.c | 29 +++++++++++++++++++++++++++++ examples/misc.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/examples/misc.c b/examples/misc.c index 892da72..1846d5e 100644 --- a/examples/misc.c +++ b/examples/misc.c @@ -21,6 +21,8 @@ * @brief */ +#define _POSIX_C_SOURCE 200809L + #include #include #include @@ -126,3 +128,30 @@ int read_file(const char *path, char **data, size_t *data_len) free(buf); return ret; } + +int read_stdin_line(const char *prompt, char **string) +{ + char *buf = NULL; + char *ret; + size_t size; + ssize_t read; + + if (prompt != NULL) + printf("%s", prompt); + + read = getline(&buf, &size, stdin); + if (read <= 0) { + free(buf); + return -1; + } + + ret = yaca_realloc(buf, read); + if (ret == NULL) { + free(buf); + return -1; + } + buf[read - 1] = '\0'; + + *string = buf; + return 0; +} diff --git a/examples/misc.h b/examples/misc.h index 7d89758..6eaa12f 100644 --- a/examples/misc.h +++ b/examples/misc.h @@ -41,4 +41,6 @@ int write_file(const char *path, char *data, size_t data_len); int read_file(const char *path, char **data, size_t *data_len); +int read_stdin_line(const char *prompt, char **string); + #endif /* MISC_H */ -- 2.7.4 From 81aa084a8f571a2fe90044dafeba8f3a98f1fa55 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 18 May 2016 14:43:21 +0200 Subject: [PATCH 12/16] yaca_key_import() implementation of password handling Change-Id: I3586b8038a711942d0998cd7130509cbbc6388ff --- src/key.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/src/key.c b/src/key.c index f31f34b..a197842 100755 --- a/src/key.c +++ b/src/key.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,18 @@ #include "internal.h" +/* This callback only exists to block the default OpenSSL one and + * allow us to check for a proper error code when the key is encrypted + */ +int password_dummy_cb(char *buf, int size, int rwflag, void *u) +{ + const char empty[] = ""; + + memcpy(buf, empty, sizeof(empty)); + + return sizeof(empty); +} + int base64_decode_length(const char *data, size_t data_len, size_t *len) { assert(data != NULL); @@ -224,18 +237,34 @@ out: return ret; } +bool check_import_wrong_pass() +{ + unsigned long err = ERR_peek_last_error(); + unsigned long err_bad_password_1 = ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT); + unsigned long err_bad_password_2 = ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); + + if (err == err_bad_password_1 || err == err_bad_password_2) + return true; + + return false; +} + int import_evp(yaca_key_h *key, yaca_key_type_e key_type, + const char *password, const char *data, size_t data_len) { assert(key != NULL); + assert(password == NULL || password[0] != '\0'); assert(data != NULL); assert(data_len != 0); int ret; BIO *src = NULL; EVP_PKEY *pkey = NULL; + bool wrong_pass = false; + pem_password_cb *cb = NULL; bool private; yaca_key_type_e type; struct yaca_key_evp_s *nk = NULL; @@ -257,46 +286,64 @@ int import_evp(yaca_key_h *key, return YACA_ERROR_INTERNAL; } + /* Block the default OpenSSL password callback */ + if (password == NULL) + cb = password_dummy_cb; + /* Possible PEM */ if (strncmp("----", data, 4) == 0) { - if (pkey == NULL) { + if (pkey == NULL && !wrong_pass) { BIO_reset(src); - pkey = PEM_read_bio_PrivateKey(src, NULL, NULL, NULL); + pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)password); + if (check_import_wrong_pass()) + wrong_pass = true; private = true; + ERROR_CLEAR(); } - if (pkey == NULL) { + if (pkey == NULL && !wrong_pass) { BIO_reset(src); - pkey = PEM_read_bio_PUBKEY(src, NULL, NULL, NULL); + pkey = PEM_read_bio_PUBKEY(src, NULL, cb, (void*)password); + if (check_import_wrong_pass()) + wrong_pass = true; private = false; + ERROR_CLEAR(); } - if (pkey == NULL) { + if (pkey == NULL && !wrong_pass) { BIO_reset(src); - X509 *x509 = PEM_read_bio_X509(src, NULL, NULL, NULL); + X509 *x509 = PEM_read_bio_X509(src, NULL, cb, (void*)password); + if (check_import_wrong_pass()) + wrong_pass = true; if (x509 != NULL) pkey = X509_get_pubkey(x509); - private = false; X509_free(x509); + private = false; + ERROR_CLEAR(); } } /* Possible DER */ else { - if (pkey == NULL) { + if (pkey == NULL && !wrong_pass) { BIO_reset(src); pkey = d2i_PrivateKey_bio(src, NULL); private = true; + ERROR_CLEAR(); } - if (pkey == NULL) { + if (pkey == NULL && !wrong_pass) { BIO_reset(src); pkey = d2i_PUBKEY_bio(src, NULL); private = false; + ERROR_CLEAR(); } } BIO_free(src); + if (wrong_pass) + return YACA_ERROR_PASSWORD_INVALID; + if (pkey == NULL) return YACA_ERROR_INVALID_ARGUMENT; @@ -872,16 +919,22 @@ API int yaca_key_import(yaca_key_h *key, if (key == NULL || data == NULL || data_len == 0) return YACA_ERROR_INVALID_ARGUMENT; + /* allow an empty password, OpenSSL returns an error with "" */ + if (password != NULL && password[0] == '\0') + password = NULL; + switch (key_type) { case YACA_KEY_TYPE_SYMMETRIC: case YACA_KEY_TYPE_DES: case YACA_KEY_TYPE_IV: + if (password != NULL) + return YACA_ERROR_INVALID_ARGUMENT; return import_simple(key, key_type, data, data_len); case YACA_KEY_TYPE_RSA_PUB: case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_DSA_PRIV: - return import_evp(key, key_type, data, data_len); + return import_evp(key, key_type, password, data, data_len); case YACA_KEY_TYPE_DH_PUB: case YACA_KEY_TYPE_DH_PRIV: case YACA_KEY_TYPE_EC_PUB: -- 2.7.4 From 30568a005257ddb2a18c04584c90c289ef718e1a Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 20 May 2016 17:16:57 +0200 Subject: [PATCH 13/16] yaca_key_export() implementation of password handling Change-Id: I17767807733346d6c6384d6fbf0bf2ffc8f076ab --- src/key.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/key.c b/src/key.c index a197842..8077f31 100755 --- a/src/key.c +++ b/src/key.c @@ -482,15 +482,18 @@ free_bio: int export_evp(struct yaca_key_evp_s *evp_key, yaca_key_file_fmt_e key_file_fmt, + const char *password, char **data, size_t *data_len) { assert(evp_key != NULL); + assert(password == NULL || password[0] != '\0'); assert(data != NULL); assert(data_len != NULL); int ret = 0; BIO *mem; + const EVP_CIPHER *enc = NULL; char *bio_data; long bio_data_len; @@ -501,6 +504,9 @@ int export_evp(struct yaca_key_evp_s *evp_key, return ret; } + if (password != NULL) + enc = EVP_aes_256_cbc(); + switch (key_file_fmt) { case YACA_KEY_FILE_FORMAT_PEM: @@ -508,11 +514,11 @@ int export_evp(struct yaca_key_evp_s *evp_key, case YACA_KEY_TYPE_RSA_PRIV: ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp), - NULL, NULL, 0, NULL, NULL); + enc, NULL, 0, NULL, (void*)password); break; case YACA_KEY_TYPE_DSA_PRIV: ret = PEM_write_bio_DSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp), - NULL, NULL, 0, NULL, NULL); + enc, NULL, 0, NULL, (void*)password); break; case YACA_KEY_TYPE_RSA_PUB: @@ -958,6 +964,13 @@ API int yaca_key_export(const yaca_key_h key, if (data == NULL || data_len == NULL) return YACA_ERROR_INVALID_ARGUMENT; + /* allow an empty password, OpenSSL returns an error with "" */ + if (password != NULL && password[0] == '\0') + password = NULL; + + if (password != NULL && simple_key != NULL) + return YACA_ERROR_INVALID_ARGUMENT; + if (key_fmt == YACA_KEY_FORMAT_DEFAULT && key_file_fmt == YACA_KEY_FILE_FORMAT_RAW && simple_key != NULL) @@ -970,7 +983,7 @@ API int yaca_key_export(const yaca_key_h key, if (key_fmt == YACA_KEY_FORMAT_DEFAULT && evp_key != NULL) - return export_evp(evp_key, key_file_fmt, data, data_len); + return export_evp(evp_key, key_file_fmt, password, data, data_len); if (key_fmt == YACA_KEY_FORMAT_PKCS8) return YACA_ERROR_NOT_IMPLEMENTED; -- 2.7.4 From dcaea3c5b4618c42b3b8e7d538a525b82c6214af Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 20 May 2016 18:08:26 +0200 Subject: [PATCH 14/16] key import/export password handling example Change-Id: I2b6da9307025e41e53dfa208c86c83bfc85ac22c --- examples/CMakeLists.txt | 1 + examples/key_password.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 examples/key_password.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4cf4681..0d6f3e1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -50,6 +50,7 @@ BUILD_EXAMPLE("yaca-example-encrypt-gcm-ccm" encrypt_aes_gcm_ccm.c) BUILD_EXAMPLE("yaca-example-sign" sign.c) BUILD_EXAMPLE("yaca-example-key-exchange" key_exchange.c) BUILD_EXAMPLE("yaca-example-key-impexp" key_import_export.c) +BUILD_EXAMPLE("yaca-example-key-password" key_password.c) INSTALL(FILES ${COMMON_SOURCES} DESTINATION ${EXAMPLES_DIR}) diff --git a/examples/key_password.c b/examples/key_password.c new file mode 100644 index 0000000..e3e20c2 --- /dev/null +++ b/examples/key_password.c @@ -0,0 +1,94 @@ +/* + * 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 "misc.h" +#include "../src/debug.h" + + +int main(int argc, char* argv[]) +{ + yaca_debug_set_error_cb(debug_func); + + yaca_key_h key = YACA_KEY_NULL; + char *k = NULL; + size_t kl; + int ret; + char *password = NULL; + + ret = yaca_init(); + if (ret != 0) + goto exit; + + ret = yaca_key_gen(&key, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_1024BIT); + if (ret != 0) + goto exit; + + ret = read_stdin_line("encryption pass: ", &password); + if (ret != 0) + goto exit; + + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, password, &k, &kl); + if (ret != 0) + goto exit; + + yaca_free(password); + yaca_key_free(key); + password = NULL; + key = YACA_KEY_NULL; + + ret = yaca_key_import(&key, YACA_KEY_TYPE_RSA_PRIV, NULL, k, kl); + if (ret == YACA_ERROR_PASSWORD_INVALID) { + ret = read_stdin_line("decryption pass: ", &password); + if (ret != 0) + goto exit; + + ret = yaca_key_import(&key, YACA_KEY_TYPE_RSA_PRIV, password, k, kl); + if (ret == YACA_ERROR_PASSWORD_INVALID) + printf("invalid password\n"); + + yaca_free(password); + password = NULL; + } + + if (ret != 0) + goto exit; + + yaca_free(k); + k = NULL; + + ret = yaca_key_export(key, YACA_KEY_FORMAT_DEFAULT, YACA_KEY_FILE_FORMAT_PEM, NULL, &k, &kl); + if (ret != 0) + goto exit; + + printf("%.*s", (int)kl, k); + +exit: + yaca_free(k); + yaca_free(password); + yaca_key_free(key); + + yaca_exit(); + + return 0; +} -- 2.7.4 From 6a81623a26e1d8c08b355570dab8ad64ed89326a Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 25 May 2016 14:04:35 +0200 Subject: [PATCH 15/16] Add support for multiple threads Change-Id: I76451bc5ea76fd2277eb62f79aa435f4b4fbe64d --- src/CMakeLists.txt | 6 ++++- src/crypto.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e21ca95..a2e511e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,9 +47,13 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES ## Link libraries ############################################################## PKG_CHECK_MODULES(YACA_DEPS REQUIRED openssl capi-base-common) +FIND_PACKAGE (Threads) + INCLUDE_DIRECTORIES(${API_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${YACA_DEPS_INCLUDE_DIRS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${YACA_DEPS_LIBRARIES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} + ${YACA_DEPS_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT}) ## Generate the pc file ######################################################## CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} @ONLY) diff --git a/src/crypto.c b/src/crypto.c index ec1d35b..d52468d 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -34,19 +35,83 @@ #include "internal.h" +static pthread_mutex_t *mutexes = NULL; + +static void locking_callback(int mode, int type, const char* file, int line) +{ + /* Ignore NULL mutexes and lock/unlock error codes as we can't do anything + * about them. */ + + if (mutexes == NULL) + return; + + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(&mutexes[type]); + else if (mode & CRYPTO_UNLOCK) + pthread_mutex_unlock(&mutexes[type]); +} + +static unsigned long thread_id_callback() +{ + return pthread_self(); +} + +static void destroy_mutexes(int count) +{ + if (mutexes != NULL) { + for (int i = 0; i < count; i++) { + /* Ignore returned value as we can't do anything about it */ + pthread_mutex_destroy(&mutexes[i]); + } + yaca_free(mutexes); + mutexes = NULL; + } +} + API int yaca_init(void) { + if (mutexes != NULL) + return YACA_ERROR_INTERNAL; // TODO introduce new one? OPENSSL_init(); OpenSSL_add_all_digests(); OpenSSL_add_all_ciphers(); + + /* enable threads support */ + mutexes = yaca_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + if (mutexes == NULL) + return YACA_ERROR_OUT_OF_MEMORY; + + for (int i = 0; i < CRYPTO_num_locks(); i++) { + if (pthread_mutex_init(&mutexes[i], NULL) != 0) { + int ret = 0; + switch (errno) { + case ENOMEM: + ret = YACA_ERROR_OUT_OF_MEMORY; + break; + case EAGAIN: + case EPERM: + case EBUSY: + case EINVAL: + default: + ret = YACA_ERROR_INTERNAL; + } + destroy_mutexes(i); + + return ret; + } + } + + CRYPTO_set_id_callback(thread_id_callback); + CRYPTO_set_locking_callback(locking_callback); + /* TODO: - We should prepare for multithreading. Either we or the user should setup static locks. We should also decide on Openssl config. Here's a good tutorial for initalization and cleanup: https://wiki.openssl.org/index.php/Library_Initialization We should also initialize the entropy for random number generator: https://wiki.openssl.org/index.php/Random_Numbers#Initialization */ + return 0; } @@ -56,6 +121,12 @@ API void yaca_exit(void) ERR_remove_thread_state(NULL); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); + + /* threads support cleanup */ + CRYPTO_set_id_callback(NULL); + CRYPTO_set_locking_callback(NULL); + + destroy_mutexes(CRYPTO_num_locks()); } API void *yaca_malloc(size_t size) -- 2.7.4 From 1793563e6ecc522c6ff2d486faeba07cd13388d6 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 27 May 2016 12:43:54 +0200 Subject: [PATCH 16/16] Modify header names according to ACR Change-Id: I0bf4ad69d5f2c5796d26e2970ab4ef9d9583b91c --- CMakeLists.txt | 2 +- api/yaca/{crypto.h => yaca_crypto.h} | 2 +- api/yaca/{digest.h => yaca_digest.h} | 2 +- api/yaca/{encrypt.h => yaca_encrypt.h} | 2 +- api/yaca/{error.h => yaca_error.h} | 0 api/yaca/{key.h => yaca_key.h} | 2 +- api/yaca/{seal.h => yaca_seal.h} | 2 +- api/yaca/{sign.h => yaca_sign.h} | 2 +- api/yaca/{simple.h => yaca_simple.h} | 2 +- api/yaca/{types.h => yaca_types.h} | 0 examples/CMakeLists.txt | 2 +- examples/digest.c | 8 ++++---- examples/encrypt.c | 10 +++++----- examples/encrypt_aes_gcm_ccm.c | 8 ++++---- examples/key_exchange.c | 6 +++--- examples/key_import_export.c | 6 +++--- examples/key_password.c | 8 ++++---- examples/misc.c | 2 +- examples/seal.c | 8 ++++---- examples/sign.c | 10 +++++----- src/CMakeLists.txt | 2 +- src/crypto.c | 4 ++-- src/digest.c | 6 +++--- src/encrypt.c | 8 ++++---- src/internal.h | 2 +- src/key.c | 6 +++--- src/seal.c | 8 ++++---- src/sign.c | 8 ++++---- src/simple.c | 12 ++++++------ src/yaca.pc.in | 2 +- 30 files changed, 71 insertions(+), 71 deletions(-) rename api/yaca/{crypto.h => yaca_crypto.h} (99%) rename api/yaca/{digest.h => yaca_digest.h} (99%) rename api/yaca/{encrypt.h => yaca_encrypt.h} (99%) rename api/yaca/{error.h => yaca_error.h} (100%) rename api/yaca/{key.h => yaca_key.h} (99%) rename api/yaca/{seal.h => yaca_seal.h} (99%) rename api/yaca/{sign.h => yaca_sign.h} (99%) rename api/yaca/{simple.h => yaca_simple.h} (99%) rename api/yaca/{types.h => yaca_types.h} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa4f6ac..e2b5e35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,7 @@ IF("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") ENDIF() ## Subdirectories ############################################################## -SET(API_FOLDER ${PROJECT_SOURCE_DIR}/api) +SET(API_FOLDER ${PROJECT_SOURCE_DIR}/api/yaca) SET(EXAMPLES_FOLDER ${PROJECT_SOURCE_DIR}/examples) SET(SRC_FOLDER ${PROJECT_SOURCE_DIR}/src) diff --git a/api/yaca/crypto.h b/api/yaca/yaca_crypto.h similarity index 99% rename from api/yaca/crypto.h rename to api/yaca/yaca_crypto.h index 5a44a9d..1fabf47 100644 --- a/api/yaca/crypto.h +++ b/api/yaca/yaca_crypto.h @@ -25,7 +25,7 @@ #define YACA_CRYPTO_H #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/api/yaca/digest.h b/api/yaca/yaca_digest.h similarity index 99% rename from api/yaca/digest.h rename to api/yaca/yaca_digest.h index 1938360..cb27246 100644 --- a/api/yaca/digest.h +++ b/api/yaca/yaca_digest.h @@ -25,7 +25,7 @@ #define YACA_DIGEST_H #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/api/yaca/encrypt.h b/api/yaca/yaca_encrypt.h similarity index 99% rename from api/yaca/encrypt.h rename to api/yaca/yaca_encrypt.h index de7bc58..94bedff 100644 --- a/api/yaca/encrypt.h +++ b/api/yaca/yaca_encrypt.h @@ -25,7 +25,7 @@ #define YACA_ENCRYPT_H #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/api/yaca/error.h b/api/yaca/yaca_error.h similarity index 100% rename from api/yaca/error.h rename to api/yaca/yaca_error.h diff --git a/api/yaca/key.h b/api/yaca/yaca_key.h similarity index 99% rename from api/yaca/key.h rename to api/yaca/yaca_key.h index e03834d..4c4642c 100755 --- a/api/yaca/key.h +++ b/api/yaca/yaca_key.h @@ -25,7 +25,7 @@ #define YACA_KEY_H #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/api/yaca/seal.h b/api/yaca/yaca_seal.h similarity index 99% rename from api/yaca/seal.h rename to api/yaca/yaca_seal.h index 2940f01..0b7f808 100644 --- a/api/yaca/seal.h +++ b/api/yaca/yaca_seal.h @@ -25,7 +25,7 @@ #define YACA_SEAL_H #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/api/yaca/sign.h b/api/yaca/yaca_sign.h similarity index 99% rename from api/yaca/sign.h rename to api/yaca/yaca_sign.h index 36ba4dc..9deebec 100644 --- a/api/yaca/sign.h +++ b/api/yaca/yaca_sign.h @@ -25,7 +25,7 @@ #define YACA_SIGN_H #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/api/yaca/simple.h b/api/yaca/yaca_simple.h similarity index 99% rename from api/yaca/simple.h rename to api/yaca/yaca_simple.h index 9c62314..f743de2 100644 --- a/api/yaca/simple.h +++ b/api/yaca/yaca_simple.h @@ -25,7 +25,7 @@ #define YACA_SIMPLE_H #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/api/yaca/types.h b/api/yaca/yaca_types.h similarity index 100% rename from api/yaca/types.h rename to api/yaca/yaca_types.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0d6f3e1..af00c1c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -20,7 +20,7 @@ # @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) # -INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/api) +INCLUDE_DIRECTORIES(${API_FOLDER}) SET(COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/lorem.c ${CMAKE_CURRENT_SOURCE_DIR}/misc.c) diff --git a/examples/digest.c b/examples/digest.c index 9e01fc1..685bd8a 100644 --- a/examples/digest.c +++ b/examples/digest.c @@ -21,10 +21,10 @@ * @brief */ -#include -#include -#include -#include +#include +#include +#include +#include #include "lorem.h" #include "misc.h" diff --git a/examples/encrypt.c b/examples/encrypt.c index ec2ee2f..0ee5e42 100644 --- a/examples/encrypt.c +++ b/examples/encrypt.c @@ -23,11 +23,11 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "lorem.h" #include "misc.h" diff --git a/examples/encrypt_aes_gcm_ccm.c b/examples/encrypt_aes_gcm_ccm.c index 4ae8ff6..7fe5305 100644 --- a/examples/encrypt_aes_gcm_ccm.c +++ b/examples/encrypt_aes_gcm_ccm.c @@ -23,10 +23,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #include "lorem.h" #include "misc.h" diff --git a/examples/key_exchange.c b/examples/key_exchange.c index 559059e..80bce46 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -23,9 +23,9 @@ #include -#include -#include -#include +#include +#include +#include #include "misc.h" #include "../src/debug.h" diff --git a/examples/key_import_export.c b/examples/key_import_export.c index 9c44266..6b647fd 100644 --- a/examples/key_import_export.c +++ b/examples/key_import_export.c @@ -23,9 +23,9 @@ #include -#include -#include -#include +#include +#include +#include #include "misc.h" #include "../src/debug.h" diff --git a/examples/key_password.c b/examples/key_password.c index e3e20c2..d76f195 100644 --- a/examples/key_password.c +++ b/examples/key_password.c @@ -18,10 +18,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "misc.h" #include "../src/debug.h" diff --git a/examples/misc.c b/examples/misc.c index 1846d5e..7eaedf3 100644 --- a/examples/misc.c +++ b/examples/misc.c @@ -29,7 +29,7 @@ #include -#include +#include #include "misc.h" diff --git a/examples/seal.c b/examples/seal.c index 0811f43..a2359a7 100644 --- a/examples/seal.c +++ b/examples/seal.c @@ -23,10 +23,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #include "lorem.h" #include "misc.h" diff --git a/examples/sign.c b/examples/sign.c index a6f4ee8..48f6dca 100644 --- a/examples/sign.c +++ b/examples/sign.c @@ -23,11 +23,11 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "lorem.h" #include "misc.h" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a2e511e..ae4168b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,7 +25,7 @@ PROJECT(yaca) MESSAGE(STATUS "") MESSAGE(STATUS "Generating makefile for the yaca...") -FILE(GLOB HEADERS ${API_FOLDER}/yaca/*.h) +FILE(GLOB HEADERS ${API_FOLDER}/*.h) FILE(GLOB SRCS *.c *.h) SET(_LIB_VERSION_ "${VERSION}") diff --git a/src/crypto.c b/src/crypto.c index d52468d..c0ce1f4 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -30,8 +30,8 @@ #include #include -#include -#include +#include +#include #include "internal.h" diff --git a/src/digest.c b/src/digest.c index 28b095e..a7e9bbe 100644 --- a/src/digest.c +++ b/src/digest.c @@ -25,9 +25,9 @@ #include -#include -#include -#include +#include +#include +#include #include "internal.h" diff --git a/src/encrypt.c b/src/encrypt.c index c3d93ee..c059c7e 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -26,10 +26,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #include "internal.h" diff --git a/src/internal.h b/src/internal.h index 16b8b38..660bbd2 100644 --- a/src/internal.h +++ b/src/internal.h @@ -29,7 +29,7 @@ #include #include -#include +#include #define API __attribute__ ((visibility ("default"))) diff --git a/src/key.c b/src/key.c index 8077f31..dd4e648 100755 --- a/src/key.c +++ b/src/key.c @@ -34,9 +34,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include "internal.h" diff --git a/src/seal.c b/src/seal.c index a3d3eb1..1dc583e 100644 --- a/src/seal.c +++ b/src/seal.c @@ -26,10 +26,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #include "internal.h" diff --git a/src/sign.c b/src/sign.c index 4f749e8..bc9b137 100644 --- a/src/sign.c +++ b/src/sign.c @@ -28,10 +28,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "internal.h" diff --git a/src/simple.c b/src/simple.c index 2597c02..04db0fa 100644 --- a/src/simple.c +++ b/src/simple.c @@ -24,12 +24,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include "internal.h" diff --git a/src/yaca.pc.in b/src/yaca.pc.in index c33c857..fe501b1 100644 --- a/src/yaca.pc.in +++ b/src/yaca.pc.in @@ -9,4 +9,4 @@ Name: yaca Description: Yet Another Crypto API Version: @_LIB_VERSION_@ Libs: -L${libdir} -l@PROJECT_NAME@ -Cflags: -I${includedir} +Cflags: -I${includedir}/yaca -- 2.7.4