From d3b861fa04beb0b1eb8777a8592b64dce90705b2 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 11 Jul 2016 13:09:21 +0200 Subject: [PATCH 01/16] Various fixes in Doxygen comments - don't include source/example directories, they only cause confusion. - don't add empty doxygen comment before a regular one. Move those comments to @file. - minor changes in the doc/ directory. Change-Id: Ie1e5e8b01cacc6a74c7201cd2652b0752091e455 --- api/yaca/yaca_crypto.h | 9 ++------- api/yaca/yaca_digest.h | 9 ++------- api/yaca/yaca_encrypt.h | 9 ++------- api/yaca/yaca_error.h | 12 ++++-------- api/yaca/yaca_key.h | 16 ++-------------- api/yaca/yaca_seal.h | 17 ++++++----------- api/yaca/yaca_sign.h | 9 ++------- api/yaca/yaca_simple.h | 24 ++++++++++-------------- api/yaca/yaca_types.h | 9 ++------- doc/doxygen.cfg | 3 +-- doc/yaca_doc.h | 2 +- doc/yaca_encryption_doc.h | 10 +++++----- doc/yaca_integrity_doc.h | 4 ++-- doc/yaca_key_doc.h | 2 +- doc/yaca_simple_doc.h | 2 +- 15 files changed, 43 insertions(+), 94 deletions(-) diff --git a/api/yaca/yaca_crypto.h b/api/yaca/yaca_crypto.h index a02583f..94ab45c 100755 --- a/api/yaca/yaca_crypto.h +++ b/api/yaca/yaca_crypto.h @@ -17,7 +17,8 @@ */ /** - * @file yaca_crypto.h + * @file yaca_crypto.h + * @brief Non crypto related functions. */ #ifndef YACA_CRYPTO_H @@ -36,12 +37,6 @@ extern "C" { */ /** - * Note: Non-Crypto Yet Another Crypto API - non crypto related functions. - * - * - */ - -/** * @brief NULL value for the crypto context. * * @since_tizen 3.0 diff --git a/api/yaca/yaca_digest.h b/api/yaca/yaca_digest.h index 85ed809..b5dfaf2 100755 --- a/api/yaca/yaca_digest.h +++ b/api/yaca/yaca_digest.h @@ -17,7 +17,8 @@ */ /** - * @file yaca_digest.h + * @file yaca_digest.h + * @brief Advanced API for the message digests. */ #ifndef YACA_DIGEST_H @@ -36,12 +37,6 @@ extern "C" { */ /** - * Note: Advanced-Digest Advanced API for the message digests. - * - * - */ - -/** * @brief Initializes a digest context. * * @since_tizen 3.0 diff --git a/api/yaca/yaca_encrypt.h b/api/yaca/yaca_encrypt.h index 16892d1..d2d2ff5 100755 --- a/api/yaca/yaca_encrypt.h +++ b/api/yaca/yaca_encrypt.h @@ -17,7 +17,8 @@ */ /** - * @file yaca_encrypt.h + * @file yaca_encrypt.h + * @brief Advanced API for the symmetric encryption. */ #ifndef YACA_ENCRYPT_H @@ -36,12 +37,6 @@ extern "C" { */ /** - * Note: Advanced-Encryption-Symmetric Advanced API for the symmetric encryption. - * - * - */ - -/** * @brief Returns the recommended/default length of the IV for a given encryption configuration. * * @since_tizen 3.0 diff --git a/api/yaca/yaca_error.h b/api/yaca/yaca_error.h index 7acb14e..03d6a57 100755 --- a/api/yaca/yaca_error.h +++ b/api/yaca/yaca_error.h @@ -17,7 +17,8 @@ */ /** - * @file yaca_error.h + * @file yaca_error.h + * @brief Error enums and defines. */ #ifndef YACA_ERROR_H @@ -29,21 +30,16 @@ extern "C" { #endif - /** * @addtogroup CAPI_YACA_ENCRYPTION_MODULE * @{ */ -/** - * Note: Error Yet another Crypto API - error enums. - * - */ - -/* define it temporary until this code goes into capi-base-common package */ +/* @cond Define it temporarily until this code goes into capi-base-common package */ #ifndef TIZEN_ERROR_YACA #define TIZEN_ERROR_YACA -0x01E30000 #endif +/* @endcond */ /** * @brief Enumeration of YACA error values. diff --git a/api/yaca/yaca_key.h b/api/yaca/yaca_key.h index f4809b6..2072cef 100755 --- a/api/yaca/yaca_key.h +++ b/api/yaca/yaca_key.h @@ -17,7 +17,8 @@ */ /** - * @file yaca_key.h + * @file yaca_key.h + * @brief Advanced API for the key and IV handling. */ #ifndef YACA_KEY_H @@ -36,12 +37,6 @@ extern "C" { */ /** - * Note: Key Advanced API for the key and IV handling. - * - * - */ - -/** * @brief NULL value for yaca_key_h type. * * @since_tizen 3.0 @@ -256,13 +251,6 @@ int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); */ void yaca_key_destroy(yaca_key_h key); - -/** - * Note: Key-Derivation Advanced API for the key derivation. - * - * - */ - /** * @brief Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). * diff --git a/api/yaca/yaca_seal.h b/api/yaca/yaca_seal.h index d97a909..a6ad219 100755 --- a/api/yaca/yaca_seal.h +++ b/api/yaca/yaca_seal.h @@ -17,7 +17,12 @@ */ /** - * @file yaca_seal.h + * @file yaca_seal.h + * @brief Advanced API for the asymmetric encryption. + * + * @details 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. */ #ifndef YACA_SEAL_H @@ -36,16 +41,6 @@ extern "C" { */ /** - * Note Advanced-Encryption-Asymmetric Advanced API for the asymmetric encryption. - * - * - * @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. - * - */ - -/** * @brief Initializes an asymmetric encryption context and generates symmetric key and IV. * * @remarks Generated symmetric key is encrypted with public key, diff --git a/api/yaca/yaca_sign.h b/api/yaca/yaca_sign.h index f06450d..0bf3097 100755 --- a/api/yaca/yaca_sign.h +++ b/api/yaca/yaca_sign.h @@ -17,7 +17,8 @@ */ /** - * @file yaca_sign.h + * @file yaca_sign.h + * @brief Advanced API for the integrity handling - HMAC, CMAC and digital signature. */ #ifndef YACA_SIGN_H @@ -36,12 +37,6 @@ extern "C" { */ /** - * Note: Advanced-Integrity Advanced API for the integrity handling - HMAC, CMAC and digital signature. - * - * - */ - -/** * @brief Initializes a signature context for asymmetric signatures. * * @since_tizen 3.0 diff --git a/api/yaca/yaca_simple.h b/api/yaca/yaca_simple.h index f0d958a..34a238c 100755 --- a/api/yaca/yaca_simple.h +++ b/api/yaca/yaca_simple.h @@ -17,7 +17,16 @@ */ /** - * @file yaca_simple.h + * @file yaca_simple.h + * @brief Simple API. + * + * @details This is simple API. + * Design constraints: + * - All operations are single-shot (no streaming possible) + * - Context is not used + * - For now only digest and symmetric ciphers are supported + * - GCM and CCM chaining is not supported + * - All outputs are allocated by the library */ #ifndef YACA_SIMPLE_H @@ -36,19 +45,6 @@ extern "C" { */ /** - * Note: Simple-API Simple API. - * - * @remarks This is simple API. - * Design constraints: - * - All operations are single-shot (no streaming possible) - * - Context is not used - * - For now only digest and symmetric ciphers are supported - * - GCM and CCM chaining is not supported - * - All outputs are allocated by the library - * - */ - -/** * @brief Calculates a digest of a buffer. * * @since_tizen 3.0 diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index f46ea34..bb47cdf 100755 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -17,7 +17,8 @@ */ /** - * @file yaca_types.h + * @file yaca_types.h + * @brief Types enums and defines. */ #ifndef YACA_TYPES_H @@ -33,12 +34,6 @@ extern "C" { */ /** - * Note: Crypto-Types Yet Another Crypto API - types. - * - * - */ - -/** * @brief The context handle. * * @since_tizen 3.0 diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg index 87e9f10..d034006 100644 --- a/doc/doxygen.cfg +++ b/doc/doxygen.cfg @@ -766,8 +766,7 @@ WARN_LOGFILE = # Note: If this tag is empty the current directory is searched. INPUT = ../api \ - ../examples \ - ../src + ../doc # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/doc/yaca_doc.h b/doc/yaca_doc.h index 3259591..41248a8 100755 --- a/doc/yaca_doc.h +++ b/doc/yaca_doc.h @@ -18,7 +18,7 @@ /** * @ingroup CAPI_SECURITY_FRAMEWORK * @defgroup CAPI_YACA_MODULE yaca crypto module - * @brief The yaca(yet another crypto api) provides a crypto function such as key management, data integrity and data en/decryption. + * @brief The YACA (Yet Another Crypto Api) provides a crypto function such as key management, data integrity and data en/decryption. * Key management provides APIs for generating secured key,importing a key trying to match it to the key_type specified and exporting a key to arbitrary format. * Data Integrity provides Advanced/Simpled API for the integrity handling - HMAC, CMAC, message digests and digital signature. * Data en/decryption provides Advanced/Simpled APIs for en/decrypting and sealing/opening a data. diff --git a/doc/yaca_encryption_doc.h b/doc/yaca_encryption_doc.h index 2fd3978..ed5403f 100755 --- a/doc/yaca_encryption_doc.h +++ b/doc/yaca_encryption_doc.h @@ -21,11 +21,11 @@ * @brief Provides APIs for encryption and decryption operations. * * @section CAPI_YACA_ENCRYPTION_MODULE_HEADER Required Header - * \#include - * \#include - * \#include - * \#include - * \#include + * \#include \n + * \#include \n + * \#include \n + * \#include \n + * \#include \n * * @section CAPI_YACA_ENCRYPTION_MODULE_OVERVIEW Overview * It provides advanced APIs for encryption/decryption operations with symmetric keys and sealing/opening operations with asymmetric keys. diff --git a/doc/yaca_integrity_doc.h b/doc/yaca_integrity_doc.h index 7598842..f10d3a4 100755 --- a/doc/yaca_integrity_doc.h +++ b/doc/yaca_integrity_doc.h @@ -21,8 +21,8 @@ * @brief Provides APIs for creating/verifying a signature and digesting a message. * * @section CAPI_YACA_INTEGRITY_MODULE_HEADER Required Header - * \#include - * \#include + * \#include \n + * \#include \n * * @section CAPI_YACA_INTEGRITY_MODULE_OVERVIEW Overview * It provides advanced APIs for creating a signature using asymmetric private key, verifying a signature using asymmetric public key, calculating a HMAC/CMAC of given message using symmetric key and calculating message digests of given message without key. diff --git a/doc/yaca_key_doc.h b/doc/yaca_key_doc.h index ff887f3..91d57e5 100755 --- a/doc/yaca_key_doc.h +++ b/doc/yaca_key_doc.h @@ -21,7 +21,7 @@ * @brief Provides APIs for key handling operations such as generating and importing a key. * * @section CAPI_YACA_KEY_MODULE_HEADER Required Header - * \#include + * \#include \n * * @section CAPI_YACA_KEY_MODULE_OVERVIEW Overview * It provides APIs for generating key using random number or password, importing a key trying to match it to the key_type specified and exporting a key to arbitrary format. diff --git a/doc/yaca_simple_doc.h b/doc/yaca_simple_doc.h index a4e6982..0e0339d 100755 --- a/doc/yaca_simple_doc.h +++ b/doc/yaca_simple_doc.h @@ -21,7 +21,7 @@ * @brief Provides simple APIs for cryptographic operations. * * @section CAPI_YACA_SIMPLE_MODULE_HEADER Required Header - * \#include + * \#include \n * * @section CAPI_YACA_SIMPLE_MODULE_OVERVIEW Overview * It provides simple APIs for encryption/decryption, signing/verification, and message digestion. -- 2.7.4 From ea84a140caeeccf26e2236875f162e6831e9fb39 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 11 Jul 2016 13:27:10 +0200 Subject: [PATCH 02/16] Convert CRLF to LF in doc/ directory Change-Id: I299418907c312731706a7d30e73fbbe679202ecc --- doc/yaca_doc.h | 124 +++++++++++++++++++++++----------------------- doc/yaca_encryption_doc.h | 70 +++++++++++++------------- doc/yaca_integrity_doc.h | 64 ++++++++++++------------ doc/yaca_key_doc.h | 62 +++++++++++------------ doc/yaca_simple_doc.h | 62 +++++++++++------------ 5 files changed, 191 insertions(+), 191 deletions(-) diff --git a/doc/yaca_doc.h b/doc/yaca_doc.h index 41248a8..86fed86 100755 --- a/doc/yaca_doc.h +++ b/doc/yaca_doc.h @@ -1,62 +1,62 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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. - */ -#ifndef __TIZEN_CORE_YACA_DOC_H__ -#define __TIZEN_CORE_YACA_DOC_H__ -/** - * @ingroup CAPI_SECURITY_FRAMEWORK - * @defgroup CAPI_YACA_MODULE yaca crypto module - * @brief The YACA (Yet Another Crypto Api) provides a crypto function such as key management, data integrity and data en/decryption. - * Key management provides APIs for generating secured key,importing a key trying to match it to the key_type specified and exporting a key to arbitrary format. - * Data Integrity provides Advanced/Simpled API for the integrity handling - HMAC, CMAC, message digests and digital signature. - * Data en/decryption provides Advanced/Simpled APIs for en/decrypting and sealing/opening a data. - * - * @section CAPI_YACA_MODULE_OVERVIEW Overview - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
APIDescription
@ref CAPI_YACA_ENCRYPTION_MODULE Provides APIs for encryption/decryption operations with symmetric keys and sealing/opening operations with asymmetric keys.
@ref CAPI_YACA_INTEGRITY_MODULE Provides APIs for creating/verifying a signature, calculating HMAC/CMAC and calculating a message digest.
@ref CAPI_YACA_KEY_MODULE Provides APIs for key handling operations such as generating, importing, and exporting a key and deriving a key from password.
@ref CAPI_YACA_SIMPLE_MODULE Provides simple APIs for cryptographic operations.
- * - * The yaca provides a crypto function such as key management, integrity handling and data en/decryption. - * Key management provides APIs for generating secured key, importing a key trying to match it to the key type specified and exporting a key to arbitrary format. - * Data Integrity provides Advanced/Simpled API for the integrity handling - HMAC, CMAC, message digest and digital signature. - * Data en/decryption provides Advanced/Simpled APIs for en/decrypting a data and creating a IV. - * - * @image html capi_yaca_overview_diagram.png - * - * The yaca provides 3 types of API. - * - key management APIs : These APIs provides generating key using random number or password, importing a key trying to match it to the key_type specified and exporting a key to arbitrary format. - * - data en/decryption APIs : These APIs provides Advanced/Simpled API for the data encryption. - * - integrity APIs : These APIs provides creating a signature using asymmetric private key, verifying a signature using asymmetric public key, calculating a HMAC/CMAC of given message using symmetric key and calculating message digests of given message without key. - * - * - */ - -#endif /* __TIZEN_CORE_YACA_DOC_H__ */ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +#ifndef __TIZEN_CORE_YACA_DOC_H__ +#define __TIZEN_CORE_YACA_DOC_H__ +/** + * @ingroup CAPI_SECURITY_FRAMEWORK + * @defgroup CAPI_YACA_MODULE yaca crypto module + * @brief The YACA (Yet Another Crypto Api) provides a crypto function such as key management, data integrity and data en/decryption. + * Key management provides APIs for generating secured key,importing a key trying to match it to the key_type specified and exporting a key to arbitrary format. + * Data Integrity provides Advanced/Simpled API for the integrity handling - HMAC, CMAC, message digests and digital signature. + * Data en/decryption provides Advanced/Simpled APIs for en/decrypting and sealing/opening a data. + * + * @section CAPI_YACA_MODULE_OVERVIEW Overview + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
APIDescription
@ref CAPI_YACA_ENCRYPTION_MODULE Provides APIs for encryption/decryption operations with symmetric keys and sealing/opening operations with asymmetric keys.
@ref CAPI_YACA_INTEGRITY_MODULE Provides APIs for creating/verifying a signature, calculating HMAC/CMAC and calculating a message digest.
@ref CAPI_YACA_KEY_MODULE Provides APIs for key handling operations such as generating, importing, and exporting a key and deriving a key from password.
@ref CAPI_YACA_SIMPLE_MODULE Provides simple APIs for cryptographic operations.
+ * + * The yaca provides a crypto function such as key management, integrity handling and data en/decryption. + * Key management provides APIs for generating secured key, importing a key trying to match it to the key type specified and exporting a key to arbitrary format. + * Data Integrity provides Advanced/Simpled API for the integrity handling - HMAC, CMAC, message digest and digital signature. + * Data en/decryption provides Advanced/Simpled APIs for en/decrypting a data and creating a IV. + * + * @image html capi_yaca_overview_diagram.png + * + * The yaca provides 3 types of API. + * - key management APIs : These APIs provides generating key using random number or password, importing a key trying to match it to the key_type specified and exporting a key to arbitrary format. + * - data en/decryption APIs : These APIs provides Advanced/Simpled API for the data encryption. + * - integrity APIs : These APIs provides creating a signature using asymmetric private key, verifying a signature using asymmetric public key, calculating a HMAC/CMAC of given message using symmetric key and calculating message digests of given message without key. + * + * + */ + +#endif /* __TIZEN_CORE_YACA_DOC_H__ */ diff --git a/doc/yaca_encryption_doc.h b/doc/yaca_encryption_doc.h index ed5403f..dff823a 100755 --- a/doc/yaca_encryption_doc.h +++ b/doc/yaca_encryption_doc.h @@ -1,35 +1,35 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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. - */ -#ifndef __TIZEN_CORE_YACA_ENCRYPTION_DOC_H__ -#define __TIZEN_CORE_YACA_ENCRYPTION_DOC_H__ -/** - * @ingroup CAPI_YACA_MODULE - * @defgroup CAPI_YACA_ENCRYPTION_MODULE yaca encryption module - * @brief Provides APIs for encryption and decryption operations. - * - * @section CAPI_YACA_ENCRYPTION_MODULE_HEADER Required Header - * \#include \n - * \#include \n - * \#include \n - * \#include \n - * \#include \n - * - * @section CAPI_YACA_ENCRYPTION_MODULE_OVERVIEW Overview - * It provides advanced APIs for encryption/decryption operations with symmetric keys and sealing/opening operations with asymmetric keys. - * - */ - -#endif /* __TIZEN_CORE_YACA_ENCRYPTION_DOC_H__ */ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +#ifndef __TIZEN_CORE_YACA_ENCRYPTION_DOC_H__ +#define __TIZEN_CORE_YACA_ENCRYPTION_DOC_H__ +/** + * @ingroup CAPI_YACA_MODULE + * @defgroup CAPI_YACA_ENCRYPTION_MODULE yaca encryption module + * @brief Provides APIs for encryption and decryption operations. + * + * @section CAPI_YACA_ENCRYPTION_MODULE_HEADER Required Header + * \#include \n + * \#include \n + * \#include \n + * \#include \n + * \#include \n + * + * @section CAPI_YACA_ENCRYPTION_MODULE_OVERVIEW Overview + * It provides advanced APIs for encryption/decryption operations with symmetric keys and sealing/opening operations with asymmetric keys. + * + */ + +#endif /* __TIZEN_CORE_YACA_ENCRYPTION_DOC_H__ */ diff --git a/doc/yaca_integrity_doc.h b/doc/yaca_integrity_doc.h index f10d3a4..023d812 100755 --- a/doc/yaca_integrity_doc.h +++ b/doc/yaca_integrity_doc.h @@ -1,32 +1,32 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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. - */ -#ifndef __TIZEN_CORE_YACA_INTEGRITY_DOC_H__ -#define __TIZEN_CORE_YACA_INTEGRITY_DOC_H__ -/** - * @ingroup CAPI_YACA_MODULE - * @defgroup CAPI_YACA_INTEGRITY_MODULE yaca integrity module - * @brief Provides APIs for creating/verifying a signature and digesting a message. - * - * @section CAPI_YACA_INTEGRITY_MODULE_HEADER Required Header - * \#include \n - * \#include \n - * - * @section CAPI_YACA_INTEGRITY_MODULE_OVERVIEW Overview - * It provides advanced APIs for creating a signature using asymmetric private key, verifying a signature using asymmetric public key, calculating a HMAC/CMAC of given message using symmetric key and calculating message digests of given message without key. - * - */ - -#endif /* __TIZEN_CORE_YACA_INTEGRITY_DOC_H__ */ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +#ifndef __TIZEN_CORE_YACA_INTEGRITY_DOC_H__ +#define __TIZEN_CORE_YACA_INTEGRITY_DOC_H__ +/** + * @ingroup CAPI_YACA_MODULE + * @defgroup CAPI_YACA_INTEGRITY_MODULE yaca integrity module + * @brief Provides APIs for creating/verifying a signature and digesting a message. + * + * @section CAPI_YACA_INTEGRITY_MODULE_HEADER Required Header + * \#include \n + * \#include \n + * + * @section CAPI_YACA_INTEGRITY_MODULE_OVERVIEW Overview + * It provides advanced APIs for creating a signature using asymmetric private key, verifying a signature using asymmetric public key, calculating a HMAC/CMAC of given message using symmetric key and calculating message digests of given message without key. + * + */ + +#endif /* __TIZEN_CORE_YACA_INTEGRITY_DOC_H__ */ diff --git a/doc/yaca_key_doc.h b/doc/yaca_key_doc.h index 91d57e5..382dfdc 100755 --- a/doc/yaca_key_doc.h +++ b/doc/yaca_key_doc.h @@ -1,31 +1,31 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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. - */ -#ifndef __TIZEN_CORE_YACA_KEY_DOC_H__ -#define __TIZEN_CORE_YACA_KEY_DOC_H__ -/** - * @ingroup CAPI_YACA_MODULE - * @defgroup CAPI_YACA_KEY_MODULE yaca key management module - * @brief Provides APIs for key handling operations such as generating and importing a key. - * - * @section CAPI_YACA_KEY_MODULE_HEADER Required Header - * \#include \n - * - * @section CAPI_YACA_KEY_MODULE_OVERVIEW Overview - * It provides APIs for generating key using random number or password, importing a key trying to match it to the key_type specified and exporting a key to arbitrary format. - * - */ - -#endif /* __TIZEN_CORE_YACA_KEY_DOC_H__ */ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +#ifndef __TIZEN_CORE_YACA_KEY_DOC_H__ +#define __TIZEN_CORE_YACA_KEY_DOC_H__ +/** + * @ingroup CAPI_YACA_MODULE + * @defgroup CAPI_YACA_KEY_MODULE yaca key management module + * @brief Provides APIs for key handling operations such as generating and importing a key. + * + * @section CAPI_YACA_KEY_MODULE_HEADER Required Header + * \#include \n + * + * @section CAPI_YACA_KEY_MODULE_OVERVIEW Overview + * It provides APIs for generating key using random number or password, importing a key trying to match it to the key_type specified and exporting a key to arbitrary format. + * + */ + +#endif /* __TIZEN_CORE_YACA_KEY_DOC_H__ */ diff --git a/doc/yaca_simple_doc.h b/doc/yaca_simple_doc.h index 0e0339d..3e1125f 100755 --- a/doc/yaca_simple_doc.h +++ b/doc/yaca_simple_doc.h @@ -1,31 +1,31 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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. - */ -#ifndef __TIZEN_CORE_YACA_SIMPLE_DOC_H__ -#define __TIZEN_CORE_YACA_SIMPLE_DOC_H__ -/** - * @ingroup CAPI_YACA_MODULE - * @defgroup CAPI_YACA_SIMPLE_MODULE yaca simple crypto module - * @brief Provides simple APIs for cryptographic operations. - * - * @section CAPI_YACA_SIMPLE_MODULE_HEADER Required Header - * \#include \n - * - * @section CAPI_YACA_SIMPLE_MODULE_OVERVIEW Overview - * It provides simple APIs for encryption/decryption, signing/verification, and message digestion. - * - */ - -#endif /* __TIZEN_CORE_YACA_SIMPLE_DOC_H__ */ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +#ifndef __TIZEN_CORE_YACA_SIMPLE_DOC_H__ +#define __TIZEN_CORE_YACA_SIMPLE_DOC_H__ +/** + * @ingroup CAPI_YACA_MODULE + * @defgroup CAPI_YACA_SIMPLE_MODULE yaca simple crypto module + * @brief Provides simple APIs for cryptographic operations. + * + * @section CAPI_YACA_SIMPLE_MODULE_HEADER Required Header + * \#include \n + * + * @section CAPI_YACA_SIMPLE_MODULE_OVERVIEW Overview + * It provides simple APIs for encryption/decryption, signing/verification, and message digestion. + * + */ + +#endif /* __TIZEN_CORE_YACA_SIMPLE_DOC_H__ */ -- 2.7.4 From 32797cd9d6badb4e8b7b4f61aebe680c2ab6ef33 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 13 Jul 2016 14:32:04 +0200 Subject: [PATCH 03/16] Fix formatting in yaca_debug_translate_error Change-Id: I125b51f447e74a79b0134192400bbc5af386419b --- src/debug.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/debug.c b/src/debug.c index f510ef3..9e5164b 100644 --- a/src/debug.c +++ b/src/debug.c @@ -47,15 +47,15 @@ API void yaca_debug_set_error_cb(yaca_error_cb fn) #define ERRORDESCRIBE(name) case name: return #name API const char *yaca_debug_translate_error(yaca_error_e err) { - switch(err) { - ERRORDESCRIBE(YACA_ERROR_NONE); - ERRORDESCRIBE(YACA_ERROR_INVALID_PARAMETER); - ERRORDESCRIBE(YACA_ERROR_OUT_OF_MEMORY); - ERRORDESCRIBE(YACA_ERROR_INTERNAL); - ERRORDESCRIBE(YACA_ERROR_DATA_MISMATCH); - ERRORDESCRIBE(YACA_ERROR_INVALID_PASSWORD); - default: return "Error not defined"; - } + switch (err) { + ERRORDESCRIBE(YACA_ERROR_NONE); + ERRORDESCRIBE(YACA_ERROR_INVALID_PARAMETER); + ERRORDESCRIBE(YACA_ERROR_OUT_OF_MEMORY); + ERRORDESCRIBE(YACA_ERROR_INTERNAL); + ERRORDESCRIBE(YACA_ERROR_DATA_MISMATCH); + ERRORDESCRIBE(YACA_ERROR_INVALID_PASSWORD); + default: return "Error not defined"; + } } #undef ERRORDESCRIBE -- 2.7.4 From 6061c8befac3feefdc17e1b0d7cd2ce8cd4c1782 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 14 Jul 2016 10:48:11 +0200 Subject: [PATCH 04/16] Fix: RC4 doesn't support block cipher modes Change-Id: Iab022f1791712e0670a02ab2262e03fc0b79c365 --- src/encrypt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/encrypt.c b/src/encrypt.c index a9f097a..1c00abf 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -289,7 +289,10 @@ int encrypt_get_algorithm(yaca_encrypt_algorithm_e algo, algo_name, bcm_name); break; case YACA_ENCRYPT_UNSAFE_RC4: - ret = snprintf(cipher_name, sizeof(cipher_name), "%s", algo_name); + if (bcm != YACA_BCM_NONE) + ret = YACA_ERROR_INVALID_PARAMETER; + else + ret = snprintf(cipher_name, sizeof(cipher_name), "%s", algo_name); break; default: return YACA_ERROR_INVALID_PARAMETER; -- 2.7.4 From 033cdfef3815b34990f8506c9457935fcc909620 Mon Sep 17 00:00:00 2001 From: Mateusz Forc Date: Thu, 14 Jul 2016 12:26:40 +0200 Subject: [PATCH 05/16] FIX: Unhandled OpenSSL error, when using invalid imported key Change-Id: I5982553ae96bd9cde491bc9ccf79ff643303cb25 --- src/encrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encrypt.c b/src/encrypt.c index 1c00abf..83ec1ba 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -421,7 +421,7 @@ static int encrypt_initialize(yaca_context_h *ctx, ret = EVP_CIPHER_CTX_set_key_length(nc->cipher_ctx, key_bit_len / 8); if (ret != 1) { ret = YACA_ERROR_INVALID_PARAMETER; - ERROR_DUMP(ret); + ERROR_CLEAR(); goto exit; } -- 2.7.4 From 596cd43cc60e86e79802965ae41f971fb0d7a801 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 8 Jul 2016 14:04:05 +0200 Subject: [PATCH 06/16] Add yaca_key_derive_dh(), define proper key types and lengths Restore YACA_KEY_TYPE_EC* defines. Change-Id: Iff2413253134d945cf0de405f5b90e159e7664ae --- api/yaca/yaca_key.h | 23 +++++++++++++++++ api/yaca/yaca_types.h | 10 ++++++++ examples/CMakeLists.txt | 3 ++- examples/key_exchange.c | 11 +++----- src/internal.h | 4 +++ src/key.c | 68 +++++++++++++++++++++++++++---------------------- src/sign.c | 8 +++--- 7 files changed, 85 insertions(+), 42 deletions(-) diff --git a/api/yaca/yaca_key.h b/api/yaca/yaca_key.h index 2072cef..c877766 100755 --- a/api/yaca/yaca_key.h +++ b/api/yaca/yaca_key.h @@ -252,6 +252,29 @@ int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); void yaca_key_destroy(yaca_key_h key); /** + * @brief Derives a key using Diffie-Helmann or EC Diffie-Helmann key exchange protocol. + * + * @since_tizen 3.0 + * + * @remarks The @a sym_key should be released using yaca_key_destroy() + * + * @param[in] prv_key Our private key + * @param[in] pub_key Peer public key + * @param[out] sym_key Shared secret, that can be used as a symmetric key + * + * @return #YACA_ERROR_NONE on success, negative on error + * @retval #YACA_ERROR_NONE Successful + * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values + * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error + * @retval #YACA_ERROR_INTERNAL Internal error + * + * @see yaca_key_destroy() + */ +int yaca_key_derive_dh(const yaca_key_h prv_key, + const yaca_key_h pub_key, + yaca_key_h *sym_key); + +/** * @brief Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). * * @since_tizen 3.0 diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index bb47cdf..cd78f88 100755 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -97,6 +97,16 @@ typedef enum { YACA_KEY_TYPE_DSA_PUB, /** Digital Signature Algorithm private key */ YACA_KEY_TYPE_DSA_PRIV, + + /** Diffie-Hellman public key */ + YACA_KEY_TYPE_DH_PUB, + /** Diffie-Hellman private key */ + YACA_KEY_TYPE_DH_PRIV, + + /** Elliptic Curve public key (for DSA and DH) */ + YACA_KEY_TYPE_EC_PUB, + /** Elliptic Curve private key (for DSA and DH) */ + YACA_KEY_TYPE_EC_PRIV } yaca_key_type_e; /** diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c1f6ef1..3eae22c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -48,8 +48,9 @@ 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) -BUILD_EXAMPLE("yaca-example-key-password" key_password.c) +BUILD_EXAMPLE("yaca-example-key-password" key_password.c) INSTALL(FILES ${COMMON_SOURCES} DESTINATION ${EXAMPLES_DIR}) diff --git a/examples/key_exchange.c b/examples/key_exchange.c index eb9beae..c825090 100644 --- a/examples/key_exchange.c +++ b/examples/key_exchange.c @@ -32,8 +32,6 @@ void key_exchange_dh(void) { -// TODO DH is not supported yet -#if 0 int ret; yaca_key_h private_key = YACA_KEY_NULL; @@ -89,13 +87,12 @@ exit: if (fp != NULL) fclose(fp); yaca_free(buffer); -#endif } -void key_exchange_ecdh(void) -{ // TODO ECDH is not supported yet #if 0 +void key_exchange_ecdh(void) +{ int ret; yaca_key_h private_key = YACA_KEY_NULL; @@ -151,8 +148,8 @@ exit: if (fp != NULL) fclose(fp); yaca_free(buffer); -#endif } +#endif int main() { @@ -163,7 +160,7 @@ int main() return ret; key_exchange_dh(); - key_exchange_ecdh(); + //key_exchange_ecdh(); yaca_cleanup(); return ret; diff --git a/src/internal.h b/src/internal.h index 762c019..e9ee271 100644 --- a/src/internal.h +++ b/src/internal.h @@ -92,6 +92,10 @@ 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 * */ struct yaca_key_evp_s { diff --git a/src/key.c b/src/key.c index e018d14..51a3993 100644 --- a/src/key.c +++ b/src/key.c @@ -385,9 +385,9 @@ int import_evp(yaca_key_h *key, type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB; break; -// case EVP_PKEY_EC: -// type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB; -// break; + case EVP_PKEY_EC: + type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB; + break; default: ret = YACA_ERROR_INVALID_PARAMETER; @@ -542,11 +542,11 @@ int export_evp_default_bio(struct yaca_key_evp_s *evp_key, ret = PEM_write_bio_PUBKEY(mem, evp_key->evp); break; -// case YACA_KEY_TYPE_DH_PRIV: -// case YACA_KEY_TYPE_DH_PUB: -// case YACA_KEY_TYPE_EC_PRIV: -// case YACA_KEY_TYPE_EC_PUB: -// TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_EC_PRIV: + case YACA_KEY_TYPE_EC_PUB: + //TODO NOT_IMPLEMENTED default: return YACA_ERROR_INVALID_PARAMETER; } @@ -575,11 +575,11 @@ int export_evp_default_bio(struct yaca_key_evp_s *evp_key, ret = i2d_PUBKEY_bio(mem, evp_key->evp); break; -// case YACA_KEY_TYPE_DH_PRIV: -// case YACA_KEY_TYPE_DH_PUB: -// case YACA_KEY_TYPE_EC_PRIV: -// case YACA_KEY_TYPE_EC_PUB: -// TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_EC_PRIV: + case YACA_KEY_TYPE_EC_PUB: + //TODO NOT_IMPLEMENTED default: return YACA_ERROR_INVALID_PARAMETER; } @@ -625,9 +625,9 @@ int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key, ret = PEM_write_bio_PKCS8PrivateKey_nid(mem, evp_key->evp, nid, NULL, 0, NULL, (void*)password); break; -// case YACA_KEY_TYPE_DH_PRIV: -// case YACA_KEY_TYPE_EC_PRIV: -// TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: + //TODO NOT_IMPLEMENTED default: /* Public keys are not supported by PKCS8 */ return YACA_ERROR_INVALID_PARAMETER; @@ -644,9 +644,9 @@ int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key, NULL, 0, NULL, (void*)password); break; -// case YACA_KEY_TYPE_DH_PRIV: -// case YACA_KEY_TYPE_EC_PRIV: -// TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: + //TODO NOT_IMPLEMENTED default: /* Public keys are not supported by PKCS8 */ return YACA_ERROR_INVALID_PARAMETER; @@ -1114,11 +1114,11 @@ API int yaca_key_import(yaca_key_type_e key_type, case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_DSA_PRIV: 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: -// case YACA_KEY_TYPE_EC_PRIV: -// TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PUB: + case YACA_KEY_TYPE_EC_PRIV: + //TODO NOT_IMPLEMENTED default: return YACA_ERROR_INVALID_PARAMETER; } @@ -1186,9 +1186,9 @@ API int yaca_key_generate(yaca_key_type_e key_type, case YACA_KEY_TYPE_DSA_PRIV: ret = generate_evp_dsa(&nk_evp, key_bit_len); break; -// case YACA_KEY_TYPE_DH_PRIV: -// case YACA_KEY_TYPE_EC_PRIV: -// TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: + //TODO NOT_IMPLEMENTED default: return YACA_ERROR_INVALID_PARAMETER; } @@ -1254,9 +1254,9 @@ API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) case YACA_KEY_TYPE_DSA_PRIV: nk->key.type = YACA_KEY_TYPE_DSA_PUB; break; -// case YACA_KEY_TYPE_EC_PRIV: -// nk->key.type = YACA_KEY_TYPE_EC_PUB; -// break; + case YACA_KEY_TYPE_EC_PRIV: + nk->key.type = YACA_KEY_TYPE_EC_PUB; + break; default: ret = YACA_ERROR_INVALID_PARAMETER; goto exit; @@ -1290,6 +1290,14 @@ API void yaca_key_destroy(yaca_key_h key) } } +API int yaca_key_derive_dh(UNUSED const yaca_key_h prv_key, + UNUSED const yaca_key_h pub_key, + UNUSED yaca_key_h *sym_key) +{ + //TODO NOT_IMPLEMENTED + return YACA_ERROR_INVALID_PARAMETER; +} + API int yaca_key_derive_pbkdf2(const char *password, const char *salt, size_t salt_len, diff --git a/src/sign.c b/src/sign.c index 58b6d03..2576501 100644 --- a/src/sign.c +++ b/src/sign.c @@ -252,8 +252,8 @@ API int yaca_sign_initialize(yaca_context_h *ctx, case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PRIV: break; -// case YACA_KEY_TYPE_EC_PRIV: -// TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_EC_PRIV: + //TODO NOT_IMPLEMENTED default: return YACA_ERROR_INVALID_PARAMETER; } @@ -504,8 +504,8 @@ API int yaca_verify_initialize(yaca_context_h *ctx, case YACA_KEY_TYPE_RSA_PUB: case YACA_KEY_TYPE_DSA_PUB: break; -// case YACA_KEY_TYPE_EC_PUB: -// TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_EC_PUB: + //TODO NOT_IMPLEMENTED default: return YACA_ERROR_INVALID_PARAMETER; } -- 2.7.4 From b22377152fa6357cc468129ef77e1fc31e2034f6 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 11 Jul 2016 12:30:52 +0200 Subject: [PATCH 07/16] Add yaca_key_derive_dh() implementation. Change-Id: I8b71e7f1a75a83aa48af5e5c46088e831400b571 --- src/key.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/src/key.c b/src/key.c index 51a3993..60112fa 100644 --- a/src/key.c +++ b/src/key.c @@ -1290,12 +1290,79 @@ API void yaca_key_destroy(yaca_key_h key) } } -API int yaca_key_derive_dh(UNUSED const yaca_key_h prv_key, - UNUSED const yaca_key_h pub_key, - UNUSED yaca_key_h *sym_key) +API int yaca_key_derive_dh(const yaca_key_h prv_key, + const yaca_key_h pub_key, + yaca_key_h *sym_key) { - //TODO NOT_IMPLEMENTED - return YACA_ERROR_INVALID_PARAMETER; + int ret; + struct yaca_key_evp_s *lprv_key = key_get_evp(prv_key); + struct yaca_key_evp_s *lpub_key = key_get_evp(pub_key); + struct yaca_key_simple_s *nk = NULL; + size_t nk_len; + EVP_PKEY_CTX *ctx; + + if (lprv_key == NULL || lpub_key == NULL || sym_key == NULL || + (!(lprv_key->key.type == YACA_KEY_TYPE_DH_PRIV && + lpub_key->key.type == YACA_KEY_TYPE_DH_PUB) + && + !(lprv_key->key.type == YACA_KEY_TYPE_EC_PRIV && + lpub_key->key.type == YACA_KEY_TYPE_EC_PUB))) + return YACA_ERROR_INVALID_PARAMETER; + + ctx = EVP_PKEY_CTX_new(lprv_key->evp, NULL); + if (ctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = EVP_PKEY_derive_init(ctx); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = EVP_PKEY_derive_set_peer(ctx, lpub_key->evp); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = EVP_PKEY_derive(ctx, NULL, &nk_len); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + if (nk_len == 0 || nk_len > SIZE_MAX / 8) { + ret = YACA_ERROR_INVALID_PARAMETER; + goto exit; + } + + ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + nk_len, (void**)&nk); + if (ret != YACA_ERROR_NONE) + goto exit; + + ret = EVP_PKEY_derive(ctx, (unsigned char*)nk->d, &nk_len); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + nk->bit_len = nk_len * 8; + nk->key.type = YACA_KEY_TYPE_SYMMETRIC; + *sym_key = (yaca_key_h)nk; + nk = NULL; + ret = YACA_ERROR_NONE; + +exit: + EVP_PKEY_CTX_free(ctx); + yaca_free(nk); + return ret; } API int yaca_key_derive_pbkdf2(const char *password, -- 2.7.4 From 5e167334a66c381c0d7164522f60e571b6437da9 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 8 Jul 2016 17:21:21 +0200 Subject: [PATCH 08/16] Add DH private key generate/public key extract. Change-Id: Ie1797d335edce2b84b1910c677aa2d70d8a2500f --- src/key.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/key.c b/src/key.c index 60112fa..cdf9ec9 100644 --- a/src/key.c +++ b/src/key.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -953,6 +954,87 @@ exit: return ret; } +int generate_evp_dh(struct yaca_key_evp_s **out, size_t key_bit_len) +{ + assert(out != NULL); + assert(key_bit_len > 0); + + int ret; + struct yaca_key_evp_s *nk; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *kctx = NULL; + EVP_PKEY *pkey = NULL; + EVP_PKEY *params = NULL; + + ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk); + if (ret != YACA_ERROR_NONE) + return ret; + + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); + if (pctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = EVP_PKEY_paramgen_init(pctx); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, key_bit_len); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = EVP_PKEY_paramgen(pctx, ¶ms); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + kctx = EVP_PKEY_CTX_new(params, NULL); + if (kctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = EVP_PKEY_keygen_init(kctx); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = EVP_PKEY_keygen(kctx, &pkey); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + nk->evp = pkey; + pkey = NULL; + *out = nk; + nk = NULL; + + ret = YACA_ERROR_NONE; + +exit: + EVP_PKEY_CTX_free(kctx); + EVP_PKEY_free(params); + EVP_PKEY_CTX_free(pctx); + yaca_free(nk); + + return ret; +} + struct yaca_key_simple_s *key_get_simple(const yaca_key_h key) { struct yaca_key_simple_s *k; @@ -989,6 +1071,8 @@ struct yaca_key_evp_s *key_get_evp(const yaca_key_h key) case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_DH_PRIV: k = (struct yaca_key_evp_s *)key; /* sanity check */ @@ -1187,6 +1271,8 @@ API int yaca_key_generate(yaca_key_type_e key_type, ret = generate_evp_dsa(&nk_evp, key_bit_len); break; case YACA_KEY_TYPE_DH_PRIV: + ret = generate_evp_dh(&nk_evp, key_bit_len); + break; case YACA_KEY_TYPE_EC_PRIV: //TODO NOT_IMPLEMENTED default: @@ -1254,6 +1340,9 @@ API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) case YACA_KEY_TYPE_DSA_PRIV: nk->key.type = YACA_KEY_TYPE_DSA_PUB; break; + case YACA_KEY_TYPE_DH_PRIV: + nk->key.type = YACA_KEY_TYPE_DH_PUB; + break; case YACA_KEY_TYPE_EC_PRIV: nk->key.type = YACA_KEY_TYPE_EC_PUB; break; -- 2.7.4 From 0280a99c6346dd9a691de6fadd7c83a5055fb9d0 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 8 Jul 2016 17:21:15 +0200 Subject: [PATCH 09/16] Merged several generate_evp_* functions into one Change-Id: I74321e421dc0c36d84f337ea4727b7467b9f4431 --- src/key.c | 248 +++++++++++++++++++------------------------------------------- 1 file changed, 77 insertions(+), 171 deletions(-) diff --git a/src/key.c b/src/key.c index cdf9ec9..706e9dc 100644 --- a/src/key.c +++ b/src/key.c @@ -811,194 +811,96 @@ exit: return ret; } -// TODO: consider merging generate_evp_*, they share awful lot of common code -int generate_evp_rsa(struct yaca_key_evp_s **out, size_t key_bit_len) +int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t key_bit_len) { assert(out != NULL); assert(key_bit_len > 0); - assert(key_bit_len % 8 == 0); + int id; + bool do_params; int ret; - struct yaca_key_evp_s *nk; - EVP_PKEY_CTX *ctx; - EVP_PKEY *pkey = NULL; - - ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk); - if (ret != YACA_ERROR_NONE) - return ret; - - ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); - if (ctx == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } - - ret = EVP_PKEY_keygen_init(ctx); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } - - ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_bit_len); - if (ret != 1) { - ret = ERROR_HANDLE(); - goto exit; - } - - ret = EVP_PKEY_keygen(ctx, &pkey); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } - - nk->evp = pkey; - pkey = NULL; - *out = nk; - nk = NULL; - - ret = YACA_ERROR_NONE; - -exit: - EVP_PKEY_CTX_free(ctx); - yaca_free(nk); - - return ret; -} - -int generate_evp_dsa(struct yaca_key_evp_s **out, size_t key_bit_len) -{ - assert(out != NULL); - assert(key_bit_len > 0); - assert(key_bit_len % 8 == 0); - - /* Openssl generates 512-bit key for key lengths smaller than 512. It also - * rounds key size to multiplication of 64. */ - if (key_bit_len < 512 || key_bit_len % 64 != 0) - return YACA_ERROR_INVALID_PARAMETER; - - int ret; - struct yaca_key_evp_s *nk; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY_CTX *kctx = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY *params = NULL; + struct yaca_key_evp_s *nk; - ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk); - if (ret != YACA_ERROR_NONE) - return ret; - - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); - if (pctx == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } - - ret = EVP_PKEY_paramgen_init(pctx); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } - - ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bit_len); - if (ret != 1) { - ret = ERROR_HANDLE(); - goto exit; - } - - ret = EVP_PKEY_paramgen(pctx, ¶ms); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + switch(key_type) { + case YACA_KEY_TYPE_RSA_PRIV: + assert(key_bit_len % 8 == 0); - kctx = EVP_PKEY_CTX_new(params, NULL); - if (kctx == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + id = EVP_PKEY_RSA; + do_params = false; + break; + case YACA_KEY_TYPE_DSA_PRIV: + assert(key_bit_len % 8 == 0); - ret = EVP_PKEY_keygen_init(kctx); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + /* Openssl generates 512-bit key for key lengths smaller than 512. It also + * rounds key size to multiplication of 64. */ + if (key_bit_len < 512 || key_bit_len % 64 != 0) + return YACA_ERROR_INVALID_PARAMETER; + id = EVP_PKEY_DSA; + do_params = true; + break; + case YACA_KEY_TYPE_DH_PRIV: + assert(key_bit_len % 8 == 0); - ret = EVP_PKEY_keygen(kctx, &pkey); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; + id = EVP_PKEY_DH; + do_params = true; + break; + default: + return YACA_ERROR_INVALID_PARAMETER; } - nk->evp = pkey; - pkey = NULL; - *out = nk; - nk = NULL; - - ret = YACA_ERROR_NONE; - -exit: - EVP_PKEY_CTX_free(kctx); - EVP_PKEY_free(params); - EVP_PKEY_CTX_free(pctx); - yaca_free(nk); - - return ret; -} - -int generate_evp_dh(struct yaca_key_evp_s **out, size_t key_bit_len) -{ - assert(out != NULL); - assert(key_bit_len > 0); - - int ret; - struct yaca_key_evp_s *nk; - EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY_CTX *kctx = NULL; - EVP_PKEY *pkey = NULL; - EVP_PKEY *params = NULL; - ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk); if (ret != YACA_ERROR_NONE) return ret; - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); - if (pctx == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + if (do_params) { + pctx = EVP_PKEY_CTX_new_id(id, NULL); + if (pctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } - ret = EVP_PKEY_paramgen_init(pctx); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + ret = EVP_PKEY_paramgen_init(pctx); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } - ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, key_bit_len); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + switch(id) { + case EVP_PKEY_DSA: + ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bit_len); + break; + case EVP_PKEY_DH: + ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, key_bit_len); + break; + default: + /* We shouldn't be here */ + assert(false); + ret = YACA_ERROR_INTERNAL; + goto exit; + } + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } - ret = EVP_PKEY_paramgen(pctx, ¶ms); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + ret = EVP_PKEY_paramgen(pctx, ¶ms); + if (ret != 1 || params == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } - kctx = EVP_PKEY_CTX_new(params, NULL); + kctx = EVP_PKEY_CTX_new(params, NULL); + } else { + kctx = EVP_PKEY_CTX_new_id(id, NULL); + } if (kctx == NULL) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -1012,8 +914,16 @@ int generate_evp_dh(struct yaca_key_evp_s **out, size_t key_bit_len) goto exit; } + if (id == EVP_PKEY_RSA) { + ret = EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, key_bit_len); + if (ret != 1) { + ret = ERROR_HANDLE(); + goto exit; + } + } + ret = EVP_PKEY_keygen(kctx, &pkey); - if (ret != 1) { + if (ret != 1 || pkey == NULL) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto exit; @@ -1265,13 +1175,9 @@ API int yaca_key_generate(yaca_key_type_e key_type, ret = generate_simple_des(&nk_simple, key_bit_len); break; case YACA_KEY_TYPE_RSA_PRIV: - ret = generate_evp_rsa(&nk_evp, key_bit_len); - break; case YACA_KEY_TYPE_DSA_PRIV: - ret = generate_evp_dsa(&nk_evp, key_bit_len); - break; case YACA_KEY_TYPE_DH_PRIV: - ret = generate_evp_dh(&nk_evp, key_bit_len); + ret = generate_evp(&nk_evp, key_type, key_bit_len); break; case YACA_KEY_TYPE_EC_PRIV: //TODO NOT_IMPLEMENTED -- 2.7.4 From f676d00009b9e7cb998ee1b1165ffb0c0838e7fe Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 11 Jul 2016 12:29:12 +0200 Subject: [PATCH 10/16] EC key generation, extract public and get_bit_length Change-Id: I55f22032778eaf6eaeb5d598eec1fe94fe684765 --- api/yaca/yaca_key.h | 9 ++++ api/yaca/yaca_types.h | 82 +++++++++++++++++++++++++++++ src/key.c | 143 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 212 insertions(+), 22 deletions(-) diff --git a/api/yaca/yaca_key.h b/api/yaca/yaca_key.h index c877766..f5de839 100755 --- a/api/yaca/yaca_key.h +++ b/api/yaca/yaca_key.h @@ -54,6 +54,8 @@ extern "C" { * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful * @retval #YACA_ERROR_INVALID_PARAMETER Either of the params is NULL + * + * @see #yaca_key_type_e */ int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type); @@ -62,6 +64,8 @@ int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type); * * @since_tizen 3.0 * + * @remarks For elliptic curves @a key_bit_len returns values from #yaca_key_bit_length_ec_e + * * @param[in] key Key which length we return * @param[out] key_bit_len Key length in bits * @@ -69,6 +73,9 @@ int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type); * @retval #YACA_ERROR_NONE Successful * @retval #YACA_ERROR_INVALID_PARAMETER Either of the params is NULL * @retval #YACA_ERROR_INTERNAL Internal error + * + * @see #yaca_key_bit_length_e + * @see #yaca_key_bit_length_ec_e */ int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len); @@ -194,6 +201,7 @@ int yaca_key_export(const yaca_key_h key, * @remarks Supported key lengths: * - RSA: length >= 256bits * - DSA: length >= 512bits, multiple of 64 + * - EC: @a key_bit_len takes values from #yaca_key_bit_length_ec_e * * @remarks The @a key should be released using yaca_key_destroy() * @@ -210,6 +218,7 @@ int yaca_key_export(const yaca_key_h key, * * @see #yaca_key_type_e * @see #yaca_key_bit_length_e + * @see #yaca_key_bit_length_ec_e * @see yaca_key_destroy() */ int yaca_key_generate(yaca_key_type_e key_type, diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index cd78f88..8c3a5b1 100755 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -33,6 +33,68 @@ extern "C" { * @{ */ +/* The format of the unsigned int used to indicate key_bit_len is as follows: + * + * Bits indicating a type: + * bits 31-30 (2 bits) indicate key_length type: + * 00(0) - regular type for RSA, DSA and DH + * 01(1) - elliptic curve + * remaining combinations reserved + * + * Bits for a regular type: + * bits 29-0 (30 bits) indicate length of the key in bits + * + * Bits for an elliptic curve type: + * bits 29-26 (4 bits) indicate type of an elliptic curve: + * 0000(0) - X9.62 Prime + * 0001(1) - SECP + * 0010(2) - SECT + * 0011(3) - Brainpool + * remaining combinations reserved (c2pnb, c2tnb, c2onb...) + * bits 25-22 (4 bits) indicate a letter: + * 0000(0) - v + * 0001(1) - r + * 0010(2) - k + * 0011(3) - t + * remaining combinations reserved (w...) + * bits 21-18 (4 bits) indicate a number: + * 0000(0) - 1 + * 0001(1) - 2 + * 0010(2) - 3 + * 0011(3) - 4 + * remaining combinations reserved + * bits 17-0 (18 bits) - length of the prime field in bits + * + * For now this is mostly used for elliptic curves. For any other keys key_bit_len can be + * passed just as a number of bits (2 most significant bits set to 00, 30 bits for bit length). + * + * For elliptic curves don't use those defines directly, use enums in yaca_key_bit_length_ec_e. + * Not all combinations are valid and other valid combinations are not guaranteed to be + * implemented (they most surely aren't). + */ + +/** @cond Don't include those defines in doxygen, they are not to be used directly */ +#define YACA_KEY_LEN_TYPE_MASK (3U << 30) + +#define YACA_KEY_LEN_TYPE_REGULAR (0U << 30) +#define YACA_KEY_LEN_TYPE_EC (1U << 30) + +#define YACA_KEY_LEN_EC_PRIME (0U << 26) +#define YACA_KEY_LEN_EC_SECP (1U << 26) +#define YACA_KEY_LEN_EC_SECT (2U << 26) +#define YACA_KEY_LEN_EC_BRAINPOOL (3U << 26) + +#define YACA_KEY_LEN_EC_V (0U << 22) +#define YACA_KEY_LEN_EC_R (1U << 22) +#define YACA_KEY_LEN_EC_K (2U << 22) +#define YACA_KEY_LEN_EC_T (3U << 22) + +#define YACA_KEY_LEN_EC_1 (0U << 18) +#define YACA_KEY_LEN_EC_2 (1U << 18) +#define YACA_KEY_LEN_EC_3 (2U << 18) +#define YACA_KEY_LEN_EC_4 (3U << 18) +/** @endcond */ + /** * @brief The context handle. * @@ -152,6 +214,26 @@ typedef enum { } yaca_key_bit_length_e; /** + * @brief Enumeration of YACA elliptic curve types with their bit lengths. + * It's meant to be passed or returned as a @a key_bit_len param + * in appropriate functions when dealing with elliptic curves. + * + * @since_tizen 3.0 + */ +typedef enum { + /** Elliptic curve prime192v1 */ + YACA_KEY_LENGTH_EC_PRIME192V1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_PRIME | YACA_KEY_LEN_EC_V | YACA_KEY_LEN_EC_1 | 192U, + /** Elliptic curve prime256v1 */ + YACA_KEY_LENGTH_EC_PRIME256V1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_PRIME | YACA_KEY_LEN_EC_V | YACA_KEY_LEN_EC_1 | 256U, + /** Elliptic curve secp256k1 */ + YACA_KEY_LENGTH_EC_SECP256K1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_K | YACA_KEY_LEN_EC_1 | 256U, + /** Elliptic curve secp384r1 */ + YACA_KEY_LENGTH_EC_SECP384R1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_R | YACA_KEY_LEN_EC_1 | 384U, + /** Elliptic curve secp521r1 */ + YACA_KEY_LENGTH_EC_SECP521R1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_R | YACA_KEY_LEN_EC_1 | 521U +} yaca_key_bit_length_ec_e; + +/** * @brief Enumeration of YACA message digest algorithms. * * @since_tizen 3.0 diff --git a/src/key.c b/src/key.c index 706e9dc..b2df812 100644 --- a/src/key.c +++ b/src/key.c @@ -37,9 +37,23 @@ #include #include #include +#include #include "internal.h" +const static struct { + size_t key_bit_len_ec; + int nid; +} EC_NID_PAIRS[] = { + {YACA_KEY_LENGTH_EC_PRIME192V1, NID_X9_62_prime192v1}, + {YACA_KEY_LENGTH_EC_PRIME256V1, NID_X9_62_prime256v1}, + {YACA_KEY_LENGTH_EC_SECP256K1, NID_secp256k1}, + {YACA_KEY_LENGTH_EC_SECP384R1, NID_secp384r1}, + {YACA_KEY_LENGTH_EC_SECP521R1, NID_secp521r1} +}; + +const static size_t EC_NID_PAIRS_SIZE = sizeof(EC_NID_PAIRS) / sizeof(EC_NID_PAIRS[0]); + struct openssl_password_data { bool password_requested; const char *password; @@ -739,6 +753,9 @@ int generate_simple(struct yaca_key_simple_s **out, size_t key_bit_len) { assert(out != NULL); + if (key_bit_len % 8 != 0) + return YACA_ERROR_INVALID_PARAMETER; + int ret; struct yaca_key_simple_s *nk; size_t key_byte_len = key_bit_len / 8; @@ -811,6 +828,38 @@ exit: return ret; } +int convert_ec_to_nid(size_t key_bit_len_ec, int *nid) +{ + assert(nid != NULL); + + size_t i; + + for (i = 0; i < EC_NID_PAIRS_SIZE; ++i) { + if (EC_NID_PAIRS[i].key_bit_len_ec == key_bit_len_ec) { + *nid = EC_NID_PAIRS[i].nid; + return YACA_ERROR_NONE; + } + } + + return YACA_ERROR_INVALID_PARAMETER; +} + +size_t convert_nid_to_ec(int nid, size_t *key_bit_len_ec) +{ + assert(key_bit_len_ec != NULL); + + size_t i; + + for (i = 0; i < EC_NID_PAIRS_SIZE; ++i) { + if (EC_NID_PAIRS[i].nid == nid) { + *key_bit_len_ec = EC_NID_PAIRS[i].key_bit_len_ec; + return YACA_ERROR_NONE; + } + } + + return YACA_ERROR_INVALID_PARAMETER; +} + int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t key_bit_len) { assert(out != NULL); @@ -825,29 +874,40 @@ int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t k EVP_PKEY *params = NULL; struct yaca_key_evp_s *nk; - switch(key_type) { + switch (key_type) { case YACA_KEY_TYPE_RSA_PRIV: - assert(key_bit_len % 8 == 0); + if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR || + key_bit_len % 8 != 0) + return YACA_ERROR_INVALID_PARAMETER; id = EVP_PKEY_RSA; do_params = false; break; case YACA_KEY_TYPE_DSA_PRIV: - assert(key_bit_len % 8 == 0); - - /* Openssl generates 512-bit key for key lengths smaller than 512. It also - * rounds key size to multiplication of 64. */ - if (key_bit_len < 512 || key_bit_len % 64 != 0) + if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR || + /* Openssl generates 512-bit key for key lengths smaller than 512. It also + * rounds key size to multiplication of 64. */ + key_bit_len < 512 || key_bit_len % 64 != 0) return YACA_ERROR_INVALID_PARAMETER; + id = EVP_PKEY_DSA; do_params = true; break; case YACA_KEY_TYPE_DH_PRIV: - assert(key_bit_len % 8 == 0); + if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR || + key_bit_len % 8 != 0) + return YACA_ERROR_INVALID_PARAMETER; id = EVP_PKEY_DH; do_params = true; break; + case YACA_KEY_TYPE_EC_PRIV: + if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_EC) + return YACA_ERROR_INVALID_PARAMETER; + + id = EVP_PKEY_EC; + do_params = true; + break; default: return YACA_ERROR_INVALID_PARAMETER; } @@ -871,19 +931,30 @@ int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t k goto exit; } - switch(id) { + switch (id) { case EVP_PKEY_DSA: ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bit_len); break; case EVP_PKEY_DH: ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, key_bit_len); break; + case EVP_PKEY_EC: { + int nid; + ret = convert_ec_to_nid(key_bit_len, &nid); + if (ret != YACA_ERROR_NONE) + goto exit; + ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid); + if (ret == 1) + ret = EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE); + break; + } default: /* We shouldn't be here */ assert(false); ret = YACA_ERROR_INTERNAL; goto exit; } + if (ret != 1) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); @@ -983,6 +1054,8 @@ struct yaca_key_evp_s *key_get_evp(const yaca_key_h key) case YACA_KEY_TYPE_DSA_PRIV: case YACA_KEY_TYPE_DH_PUB: case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PUB: + case YACA_KEY_TYPE_EC_PRIV: k = (struct yaca_key_evp_s *)key; /* sanity check */ @@ -1068,16 +1141,44 @@ API int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len) if (evp_key != NULL) { int ret; - // TODO: handle ECC keys when they're implemented - ret = EVP_PKEY_bits(evp_key->evp); - if (ret <= 0) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - return ret; - } + switch (evp_key->key.type) { + case YACA_KEY_TYPE_RSA_PRIV: + case YACA_KEY_TYPE_RSA_PUB: + case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DSA_PUB: + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_DH_PUB: + ret = EVP_PKEY_bits(evp_key->evp); + if (ret <= 0) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + return ret; + } - *key_bit_len = ret; - return YACA_ERROR_NONE; + *key_bit_len = ret; + return YACA_ERROR_NONE; + case YACA_KEY_TYPE_EC_PRIV: + case YACA_KEY_TYPE_EC_PUB: { + assert(EVP_PKEY_type(evp_key->evp->type) == EVP_PKEY_EC); + + const EC_KEY *eck = EVP_PKEY_get0(evp_key->evp); + const EC_GROUP *ecg = EC_KEY_get0_group(eck); + int flags = EC_GROUP_get_asn1_flag(ecg); + int nid; + + if (!(flags & OPENSSL_EC_NAMED_CURVE)) + /* This is case of a custom (not named) curve, that can happen when someone + imports such a key into YACA. There is nothing that can be returned here */ + return YACA_ERROR_INVALID_PARAMETER; + + nid = EC_GROUP_get_curve_name(ecg); + return convert_nid_to_ec(nid, key_bit_len); + } + default: + /* We shouldn't be here */ + assert(false); + return YACA_ERROR_INTERNAL; + } } return YACA_ERROR_INVALID_PARAMETER; @@ -1163,7 +1264,7 @@ API int yaca_key_generate(yaca_key_type_e key_type, struct yaca_key_simple_s *nk_simple = NULL; struct yaca_key_evp_s *nk_evp = NULL; - if (key == NULL || key_bit_len == 0 || key_bit_len % 8 != 0) + if (key == NULL || key_bit_len == 0) return YACA_ERROR_INVALID_PARAMETER; switch (key_type) { @@ -1177,10 +1278,9 @@ API int yaca_key_generate(yaca_key_type_e key_type, case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PRIV: case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: ret = generate_evp(&nk_evp, key_type, key_bit_len); break; - case YACA_KEY_TYPE_EC_PRIV: - //TODO NOT_IMPLEMENTED default: return YACA_ERROR_INVALID_PARAMETER; } @@ -1197,7 +1297,6 @@ API int yaca_key_generate(yaca_key_type_e key_type, } return YACA_ERROR_NONE; - } API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) -- 2.7.4 From 2006afb55636fb7cb28f5ff648d472012cfd98c9 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 18 Jul 2016 10:07:43 +0200 Subject: [PATCH 11/16] =?utf8?q?Fix=20error:=20'static=E2=80=99=20is=20not?= =?utf8?q?=20at=20beginning=20of=20declaration?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: Ia49af914337e6fb2eef507ac8f906184092839a5 --- src/key.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/key.c b/src/key.c index b2df812..39202ae 100644 --- a/src/key.c +++ b/src/key.c @@ -41,7 +41,7 @@ #include "internal.h" -const static struct { +static const struct { size_t key_bit_len_ec; int nid; } EC_NID_PAIRS[] = { @@ -52,7 +52,7 @@ const static struct { {YACA_KEY_LENGTH_EC_SECP521R1, NID_secp521r1} }; -const static size_t EC_NID_PAIRS_SIZE = sizeof(EC_NID_PAIRS) / sizeof(EC_NID_PAIRS[0]); +static const size_t EC_NID_PAIRS_SIZE = sizeof(EC_NID_PAIRS) / sizeof(EC_NID_PAIRS[0]); struct openssl_password_data { bool password_requested; -- 2.7.4 From 70f7be1c16429a6d3458cf941b57f08edbc036b9 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Thu, 14 Jul 2016 17:59:16 +0200 Subject: [PATCH 12/16] API change/extension for key handling (parameters and DH RFC5114) New functions: - yaca_key_generate_from_parameters() - yaca_key_extract_parameters() New functionality: - yaca_key_generate() - yaca_key_import() - yaca_key_export() New defines/enums: - YACA_KEY_TYPE_*_PARAMS - YACA_KEY_LENGTH_DH_GENERATOR_* - yaca_key_bit_length_dh_rfc_e; - yaca_key_bit_length_ec_e; Change-Id: I4fd4a0fa00c7f340a1dcf37fbe39b6f80d95484c --- api/yaca/yaca_key.h | 100 +++++++++++++++++++++++++++------ api/yaca/yaca_types.h | 153 +++++++++++++++++++++++++++++++++++++------------- src/key.c | 8 +-- 3 files changed, 202 insertions(+), 59 deletions(-) diff --git a/api/yaca/yaca_key.h b/api/yaca/yaca_key.h index f5de839..802c4cc 100755 --- a/api/yaca/yaca_key.h +++ b/api/yaca/yaca_key.h @@ -64,7 +64,11 @@ int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type); * * @since_tizen 3.0 * - * @remarks For elliptic curves @a key_bit_len returns values from #yaca_key_bit_length_ec_e + * @remarks For Diffie-Helmann @a key_bit_len returns prime length in bits. Values + * used to generate the key/parammeters in yaca_key_generate() are not + * restored. Neither generator number nor values from #yaca_key_bit_length_dh_rfc_e. + * + * @remarks For Elliptic Curves @a key_bit_len returns values from #yaca_key_bit_length_ec_e. * * @param[in] key Key which length we return * @param[out] key_bit_len Key length in bits @@ -75,15 +79,19 @@ int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type); * @retval #YACA_ERROR_INTERNAL Internal error * * @see #yaca_key_bit_length_e + * @see #yaca_key_bit_length_dh_rfc_e * @see #yaca_key_bit_length_ec_e */ int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len); /** - * @brief Imports a key. + * @brief Imports a key or key generation parameters. * * @since_tizen 3.0 * + * @remarks Everywhere where either a key (of any type) or an asymmetric key is referred + * in the documentation of this function key generator parameters are also included. + * * @remarks This function imports a key trying to match it to the @a key_type specified. * It should autodetect both the key format and the file format. * @@ -91,10 +99,10 @@ int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len); * binary format are supported. * For asymmetric keys PEM and DER file formats are supported. * - * @remarks 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. + * @remarks Asymmetric keys can be in their default ASN1 structure formats (like + * PKCS#1, SSleay or PKCS#3). Private asymmetric keys can also be in + * PKCS#8 format. Additionally it is possible to import public RSA/DSA/EC + * keys from X509 certificate. * * @remarks 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 @@ -133,16 +141,19 @@ int yaca_key_import(yaca_key_type_e key_type, yaca_key_h *key); /** - * @brief Exports a key to arbitrary format. Export may fail if key is HW-based. + * @brief Exports a key or key generation parameters to arbitrary format. * * @since_tizen 3.0 * + * @remarks Everywhere where either a key (of any type) or an asymmetric key is referred + * in the documentation of this function key generator parameters are also included. + * * @remarks This function exports the key to an arbitrary key format and key file format. * * @remarks 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 keys and SSLeay for DSA keys. + * keys (or IV), for asymmetric keys it will export to their + * default ASN1 structure format (e.g. PKCS#1, SSLeay, PKCS#3). * - #YACA_KEY_FORMAT_PKCS8: this will only work for private asymmetric keys. * * @remarks The following file formats are supported: @@ -160,9 +171,9 @@ int yaca_key_import(yaca_key_type_e key_type, * file formats). If no password is provided the #YACA_ERROR_INVALID_PARAMETER will * be returned. The encryption algorithm used in this case is PBE with DES-CBC. * - * @remakrs Encryption is not supported for the symmetric and public keys in all their - * supported formats. If a password is provided in such case the - * #YACA_ERROR_INVALID_PARAMETER will be returned. + * @remarks Encryption is not supported for the symmetric, public keys and key generation + * parameters in all their supported formats. If a password is provided in such + * case the #YACA_ERROR_INVALID_PARAMETER will be returned. * * @param[in] key Key to be exported * @param[in] key_fmt Format of the key @@ -192,16 +203,20 @@ int yaca_key_export(const yaca_key_h key, size_t *data_len); /** - * @brief Generates a secure key (or an initialization vector). + * @brief Generates a secure key or key generation parameters (or an initialization vector). * * @since_tizen 3.0 * - * @remarks This function is used to generate symmetric and private asymmetric keys. + * @remarks This function is used to generate symmetric keys, private asymmetric keys + * or key generation parameters for key types that support them (DSA, DH and EC). * * @remarks Supported key lengths: * - RSA: length >= 256bits * - DSA: length >= 512bits, multiple of 64 - * - EC: @a key_bit_len takes values from #yaca_key_bit_length_ec_e + * - DH: a value taken from #yaca_key_bit_length_dh_rfc_e or + * (YACA_KEY_LENGTH_DH_GENERATOR_* | prime_length_in_bits), + * where prime_length_in_bits can be any positive number + * - EC: a value taken from #yaca_key_bit_length_ec_e * * @remarks The @a key should be released using yaca_key_destroy() * @@ -218,6 +233,9 @@ int yaca_key_export(const yaca_key_h key, * * @see #yaca_key_type_e * @see #yaca_key_bit_length_e + * @see #yaca_key_bit_length_dh_rfc_e + * @see #YACA_KEY_LENGTH_DH_GENERATOR_2 + * @see #YACA_KEY_LENGTH_DH_GENERATOR_5 * @see #yaca_key_bit_length_ec_e * @see yaca_key_destroy() */ @@ -226,14 +244,39 @@ int yaca_key_generate(yaca_key_type_e key_type, yaca_key_h *key); /** + * @brief Generates a secure private asymmetric key from parameters. + * + * @since_tizen 3.0 + * + * @remarks This function is used to generate private asymmetric keys + * based on pre-generated parameters. + * + * @remarks The @a key should be released using yaca_key_destroy() + * + * @param[in] params Pre-generated parameters + * @param[out] prv_key Newly generated private key + * + * @return #YACA_ERROR_NONE on success, negative on error + * @retval #YACA_ERROR_NONE Successful + * @retval #YACA_ERROR_INVALID_PARAMETER key is NULL or incorrect @a params + * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error + * @retval #YACA_ERROR_INTERNAL Internal error + * + * @see yaca_key_destroy() + * @see yaca_key_generate() + * @see yaca_key_extract_parameters() + */ +int yaca_key_generate_from_parameters(const yaca_key_h params, yaca_key_h *prv_key); + +/** * @brief Extracts public key from a private one. * * @since_tizen 3.0 * * @remarks The @a pub_key should be released using yaca_key_destroy() * - * @param[in] prv_key Private key to extract the public one from - * @param[out] pub_key Extracted public key + * @param[in] prv_key Private key to extract the public one from + * @param[out] pub_key Extracted public key * * @return #YACA_ERROR_NONE on success, negative on error * @retval #YACA_ERROR_NONE Successful @@ -248,6 +291,29 @@ int yaca_key_generate(yaca_key_type_e key_type, int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key); /** + * @brief Extracts parameters from a private or a public key. + * + * @since_tizen 3.0 + * + * @remarks The @a params_key should be released using yaca_key_destroy() + * + * @param[in] key A key to extract the parameters from + * @param[out] params Extracted parameters + * + * @return #YACA_ERROR_NONE on success, negative on error + * @retval #YACA_ERROR_NONE Successful + * @retval #YACA_ERROR_INVALID_PARAMETER @a key is of invalid type or @a params is NULL + * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error + * @retval #YACA_ERROR_INTERNAL Internal error + * + * @see yaca_key_generate() + * @see yaca_key_generate_from_parameters() + * @see yaca_key_import() + * @see yaca_key_destroy() + */ +int yaca_key_extract_parameters(const yaca_key_h key, yaca_key_h *params); + +/** * @brief Release the key created by the library. Passing YACA_KEY_NULL is allowed. * * @since_tizen 3.0 diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index 8c3a5b1..c93ea2c 100755 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -36,63 +36,103 @@ extern "C" { /* The format of the unsigned int used to indicate key_bit_len is as follows: * * Bits indicating a type: - * bits 31-30 (2 bits) indicate key_length type: - * 00(0) - regular type for RSA, DSA and DH - * 01(1) - elliptic curve + * bits 31-28 (4 bits) indicate key_length type: + * 0000(0) - regular type for RSA, DSA + * 0001(1) - DH with specified generator + * 0010(2) - DH with RFC 5114 + * 0011(3) - elliptic curve * remaining combinations reserved * * Bits for a regular type: - * bits 29-0 (30 bits) indicate length of the key in bits + * bits 27-0 (28 bits) indicate length of the key in bits + * + * Bits for a DH with specified generator number: + * bits 27-24 (4 bits) indicate DH generator + * 0000(0) - generator 2 + * 0001(1) - generator 5 + * remaining combinations reserved + * bits 23-16 (8 bits) reserved + * bits 15-0 (16 bits) length of the safe prime in bits + * + * Bits for a DH with RFC 5114: + * bits 27-24 (4 bits) indicate a bit subgroup: + * 0000(0) - 160 + * 0001(1) - 224 + * 0010(2) - 256 + * remaining combinations reserved + * bits 23-16 (8 bits) reserved + * bits 15-0 (16 bits) length of the safe prime in bits * * Bits for an elliptic curve type: - * bits 29-26 (4 bits) indicate type of an elliptic curve: + * bits 27-24 (4 bits) indicate type of an elliptic curve: * 0000(0) - X9.62 Prime * 0001(1) - SECP * 0010(2) - SECT * 0011(3) - Brainpool * remaining combinations reserved (c2pnb, c2tnb, c2onb...) - * bits 25-22 (4 bits) indicate a letter: + * bits 23-20 (4 bits) indicate a letter: * 0000(0) - v * 0001(1) - r * 0010(2) - k * 0011(3) - t * remaining combinations reserved (w...) - * bits 21-18 (4 bits) indicate a number: + * bits 19-16 (4 bits) indicate a number: * 0000(0) - 1 * 0001(1) - 2 * 0010(2) - 3 * 0011(3) - 4 * remaining combinations reserved - * bits 17-0 (18 bits) - length of the prime field in bits + * bits 15-0 (16 bits) - length of the prime field in bits + * + * Those bits are used for DH and EC. For any other keys key_bit_len can be passed just + * as a number of bits (4 most significant bits set to 0000, 28 bits for bit length). + * + * In any case those defines are not be used directly. * - * For now this is mostly used for elliptic curves. For any other keys key_bit_len can be - * passed just as a number of bits (2 most significant bits set to 00, 30 bits for bit length). + * For DH keys use YACA_KEY_LENGTH_DH_GENERATOR_* or'ed with safe prime length. + * Alternatively one can use values from yaca_key_bit_length_dh_rfc_e enum to use + * RFC 5114 parameters. * - * For elliptic curves don't use those defines directly, use enums in yaca_key_bit_length_ec_e. - * Not all combinations are valid and other valid combinations are not guaranteed to be - * implemented (they most surely aren't). + * For elliptic curves use values from yaca_key_bit_length_ec_e enum. */ /** @cond Don't include those defines in doxygen, they are not to be used directly */ -#define YACA_KEY_LEN_TYPE_MASK (3U << 30) -#define YACA_KEY_LEN_TYPE_REGULAR (0U << 30) -#define YACA_KEY_LEN_TYPE_EC (1U << 30) - -#define YACA_KEY_LEN_EC_PRIME (0U << 26) -#define YACA_KEY_LEN_EC_SECP (1U << 26) -#define YACA_KEY_LEN_EC_SECT (2U << 26) -#define YACA_KEY_LEN_EC_BRAINPOOL (3U << 26) - -#define YACA_KEY_LEN_EC_V (0U << 22) -#define YACA_KEY_LEN_EC_R (1U << 22) -#define YACA_KEY_LEN_EC_K (2U << 22) -#define YACA_KEY_LEN_EC_T (3U << 22) - -#define YACA_KEY_LEN_EC_1 (0U << 18) -#define YACA_KEY_LEN_EC_2 (1U << 18) -#define YACA_KEY_LEN_EC_3 (2U << 18) -#define YACA_KEY_LEN_EC_4 (3U << 18) +/* types */ +#define YACA_INTERNAL_KEYLEN_TYPE_MASK (0xF << 28) +#define YACA_INTERNAL_KEYLEN_TYPE_BITS (0U << 28) +#define YACA_INTERNAL_KEYLEN_TYPE_DH (1U << 28) +#define YACA_INTERNAL_KEYLEN_TYPE_DH_RFC (2U << 28) +#define YACA_INTERNAL_KEYLEN_TYPE_EC (3U << 28) + +/* DH type */ +#define YACA_INTERNAL_KEYLEN_DH_GEN_MASK (0xF << 24) +#define YACA_INTERNAL_KEYLEN_DH_GEN_2 (0U << 24) +#define YACA_INTERNAL_KEYLEN_DH_GEN_5 (1U << 24) + +#define YACA_INTERNAL_KEYLEN_DH_PRIME_MASK (0xFFFF << 0) + +/* DH_RFC type */ +#define YACA_INTERNAL_KEYLEN_DH_RFC_MASK (0xF << 24) +#define YACA_INTERNAL_KEYLEN_DH_RFC_160 (0U << 24) +#define YACA_INTERNAL_KEYLEN_DH_RFC_224 (1U << 24) +#define YACA_INTERNAL_KEYLEN_DH_RFC_256 (2U << 24) + +/* EC type */ +#define YACA_INTERNAL_KEYLEN_EC_PRIME (0U << 24) +#define YACA_INTERNAL_KEYLEN_EC_SECP (1U << 24) +#define YACA_INTERNAL_KEYLEN_EC_SECT (2U << 24) +#define YACA_INTERNAL_KEYLEN_EC_BRAINPOOL (3U << 24) + +#define YACA_INTERNAL_KEYLEN_EC_V (0U << 20) +#define YACA_INTERNAL_KEYLEN_EC_R (1U << 20) +#define YACA_INTERNAL_KEYLEN_EC_K (2U << 20) +#define YACA_INTERNAL_KEYLEN_EC_T (3U << 20) + +#define YACA_INTERNAL_KEYLEN_EC_1 (0U << 16) +#define YACA_INTERNAL_KEYLEN_EC_2 (1U << 16) +#define YACA_INTERNAL_KEYLEN_EC_3 (2U << 16) +#define YACA_INTERNAL_KEYLEN_EC_4 (3U << 16) /** @endcond */ /** @@ -103,7 +143,7 @@ extern "C" { typedef struct yaca_context_s *yaca_context_h; /** - * @brief The key handle. + * @brief The handle of a key, an IV or a key generation parameters. * * @since_tizen 3.0 */ @@ -168,7 +208,14 @@ typedef enum { /** Elliptic Curve public key (for DSA and DH) */ YACA_KEY_TYPE_EC_PUB, /** Elliptic Curve private key (for DSA and DH) */ - YACA_KEY_TYPE_EC_PRIV + YACA_KEY_TYPE_EC_PRIV, + + /** Digital Signature Algorithm parameters */ + YACA_KEY_TYPE_DSA_PARAMS, + /** Diffie-Hellman parameters */ + YACA_KEY_TYPE_DH_PARAMS, + /** Elliptic Curve parameters */ + YACA_KEY_TYPE_EC_PARAMS } yaca_key_type_e; /** @@ -222,18 +269,48 @@ typedef enum { */ typedef enum { /** Elliptic curve prime192v1 */ - YACA_KEY_LENGTH_EC_PRIME192V1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_PRIME | YACA_KEY_LEN_EC_V | YACA_KEY_LEN_EC_1 | 192U, + YACA_KEY_LENGTH_EC_PRIME192V1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_PRIME | YACA_INTERNAL_KEYLEN_EC_V | YACA_INTERNAL_KEYLEN_EC_1 | 192U, /** Elliptic curve prime256v1 */ - YACA_KEY_LENGTH_EC_PRIME256V1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_PRIME | YACA_KEY_LEN_EC_V | YACA_KEY_LEN_EC_1 | 256U, + YACA_KEY_LENGTH_EC_PRIME256V1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_PRIME | YACA_INTERNAL_KEYLEN_EC_V | YACA_INTERNAL_KEYLEN_EC_1 | 256U, /** Elliptic curve secp256k1 */ - YACA_KEY_LENGTH_EC_SECP256K1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_K | YACA_KEY_LEN_EC_1 | 256U, + YACA_KEY_LENGTH_EC_SECP256K1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_SECP | YACA_INTERNAL_KEYLEN_EC_K | YACA_INTERNAL_KEYLEN_EC_1 | 256U, /** Elliptic curve secp384r1 */ - YACA_KEY_LENGTH_EC_SECP384R1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_R | YACA_KEY_LEN_EC_1 | 384U, + YACA_KEY_LENGTH_EC_SECP384R1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_SECP | YACA_INTERNAL_KEYLEN_EC_R | YACA_INTERNAL_KEYLEN_EC_1 | 384U, /** Elliptic curve secp521r1 */ - YACA_KEY_LENGTH_EC_SECP521R1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_R | YACA_KEY_LEN_EC_1 | 521U + YACA_KEY_LENGTH_EC_SECP521R1 = YACA_INTERNAL_KEYLEN_TYPE_EC | YACA_INTERNAL_KEYLEN_EC_SECP | YACA_INTERNAL_KEYLEN_EC_R | YACA_INTERNAL_KEYLEN_EC_1 | 521U } yaca_key_bit_length_ec_e; /** + * @brief A value indicating generator equal 2 for DH parameters. + * To be or'ed with safe prime length in bits. Prime length is recommended + * to be 2048 bits or higher. + */ +#define YACA_KEY_LENGTH_DH_GENERATOR_2 (YACA_INTERNAL_KEYLEN_TYPE_DH | YACA_INTERNAL_KEYLEN_DH_GEN_2) +/** + * @brief A value indicating generator equal 5 for DH parameters. + * To be or'ed with safe prime length in bits. Prime length is recommended + * to be 2048 bits or higher. + */ +#define YACA_KEY_LENGTH_DH_GENERATOR_5 (YACA_INTERNAL_KEYLEN_TYPE_DH | YACA_INTERNAL_KEYLEN_DH_GEN_5) + +/** + * @brief Enumeration of YACA DH parameters taken from RFC 5114. + * It's meant to be passed or returned as a @a key_bit_len param + * in appropriate functions when dealing with DH and wanting to + * use RFC 5114 values. + * + * @since_tizen 3.0 + */ +typedef enum { + /** RFC 5114 DH parameters 1024_160 */ + YACA_KEY_LENGTH_DH_RFC_1024_160 = YACA_INTERNAL_KEYLEN_TYPE_DH_RFC | YACA_INTERNAL_KEYLEN_DH_RFC_160 | 1024U, + /** RFC 5114 DH parameters 2048_224 */ + YACA_KEY_LENGTH_DH_RFC_2048_224 = YACA_INTERNAL_KEYLEN_TYPE_DH_RFC | YACA_INTERNAL_KEYLEN_DH_RFC_224 | 2048U, + /** RFC 5114 DH parameters 2048_256 */ + YACA_KEY_LENGTH_DH_RFC_2048_256 = YACA_INTERNAL_KEYLEN_TYPE_DH_RFC | YACA_INTERNAL_KEYLEN_DH_RFC_256 | 2048U +} yaca_key_bit_length_dh_rfc_e; + +/** * @brief Enumeration of YACA message digest algorithms. * * @since_tizen 3.0 diff --git a/src/key.c b/src/key.c index 39202ae..26dc737 100644 --- a/src/key.c +++ b/src/key.c @@ -876,7 +876,7 @@ int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t k switch (key_type) { case YACA_KEY_TYPE_RSA_PRIV: - if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR || + if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || key_bit_len % 8 != 0) return YACA_ERROR_INVALID_PARAMETER; @@ -884,7 +884,7 @@ int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t k do_params = false; break; case YACA_KEY_TYPE_DSA_PRIV: - if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR || + if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || /* Openssl generates 512-bit key for key lengths smaller than 512. It also * rounds key size to multiplication of 64. */ key_bit_len < 512 || key_bit_len % 64 != 0) @@ -894,7 +894,7 @@ int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t k do_params = true; break; case YACA_KEY_TYPE_DH_PRIV: - if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR || + if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || key_bit_len % 8 != 0) return YACA_ERROR_INVALID_PARAMETER; @@ -902,7 +902,7 @@ int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t k do_params = true; break; case YACA_KEY_TYPE_EC_PRIV: - if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_EC) + if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_EC) return YACA_ERROR_INVALID_PARAMETER; id = EVP_PKEY_EC; -- 2.7.4 From f70aa79a8b2e4b38f7bf256f74f269bbea057c20 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 15 Jul 2016 14:37:51 +0200 Subject: [PATCH 13/16] Key generation re-work to handle parameters and 2 stage keygen Change-Id: Ia427b82a5d6d7ded59144b0638a866ae13d2fa21 --- src/key.c | 430 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 290 insertions(+), 140 deletions(-) diff --git a/src/key.c b/src/key.c index 26dc737..ce2008c 100644 --- a/src/key.c +++ b/src/key.c @@ -41,19 +41,6 @@ #include "internal.h" -static const struct { - size_t key_bit_len_ec; - int nid; -} EC_NID_PAIRS[] = { - {YACA_KEY_LENGTH_EC_PRIME192V1, NID_X9_62_prime192v1}, - {YACA_KEY_LENGTH_EC_PRIME256V1, NID_X9_62_prime256v1}, - {YACA_KEY_LENGTH_EC_SECP256K1, NID_secp256k1}, - {YACA_KEY_LENGTH_EC_SECP384R1, NID_secp384r1}, - {YACA_KEY_LENGTH_EC_SECP521R1, NID_secp521r1} -}; - -static const size_t EC_NID_PAIRS_SIZE = sizeof(EC_NID_PAIRS) / sizeof(EC_NID_PAIRS[0]); - struct openssl_password_data { bool password_requested; const char *password; @@ -82,6 +69,55 @@ int openssl_password_cb_error(UNUSED char *buf, UNUSED int size, UNUSED int rwfl return 0; } +static const struct { + size_t ec; + int nid; +} EC_NID_PAIRS[] = { + {YACA_KEY_LENGTH_EC_PRIME192V1, NID_X9_62_prime192v1}, + {YACA_KEY_LENGTH_EC_PRIME256V1, NID_X9_62_prime256v1}, + {YACA_KEY_LENGTH_EC_SECP256K1, NID_secp256k1}, + {YACA_KEY_LENGTH_EC_SECP384R1, NID_secp384r1}, + {YACA_KEY_LENGTH_EC_SECP521R1, NID_secp521r1} +}; + +static const size_t EC_NID_PAIRS_SIZE = sizeof(EC_NID_PAIRS) / sizeof(EC_NID_PAIRS[0]); + +static const struct { + int evp_id; + yaca_key_type_e priv; + yaca_key_type_e pub; + yaca_key_type_e params; +} KEY_TYPES_PARAMS[] = { + {EVP_PKEY_RSA, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_TYPE_RSA_PUB, -1}, + {EVP_PKEY_DSA, YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_TYPE_DSA_PUB, YACA_KEY_TYPE_DSA_PARAMS}, + {EVP_PKEY_DH, YACA_KEY_TYPE_DH_PRIV, YACA_KEY_TYPE_DH_PUB, YACA_KEY_TYPE_DH_PARAMS}, + {EVP_PKEY_EC, YACA_KEY_TYPE_EC_PRIV, YACA_KEY_TYPE_EC_PUB, YACA_KEY_TYPE_EC_PARAMS} +}; + +static const size_t KEY_TYPES_PARAMS_SIZE = sizeof(KEY_TYPES_PARAMS) / sizeof(KEY_TYPES_PARAMS[0]); + +#define CONVERT_TYPES_TEMPLATE(data, src_type, src, dst_type, dst) \ + static int convert_##src##_to_##dst (src_type src, dst_type *dst) \ + { \ + assert(dst != NULL); \ + size_t i; \ + for (i = 0; i < data##_SIZE; ++i) \ + if (data[i].src == src) { \ + if (data[i].dst != (dst_type)-1) { \ + *dst = data[i].dst; \ + return YACA_ERROR_NONE; \ + } \ + } \ + return YACA_ERROR_INVALID_PARAMETER; \ + } + +CONVERT_TYPES_TEMPLATE(EC_NID_PAIRS, int, nid, size_t, ec) +CONVERT_TYPES_TEMPLATE(EC_NID_PAIRS, size_t, ec, int, nid) + +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, int, evp_id) +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, priv, int, evp_id) +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, yaca_key_type_e, priv) + int base64_decode_length(const char *data, size_t data_len, size_t *len) { assert(data != NULL); @@ -828,149 +864,160 @@ exit: return ret; } -int convert_ec_to_nid(size_t key_bit_len_ec, int *nid) -{ - assert(nid != NULL); - - size_t i; - - for (i = 0; i < EC_NID_PAIRS_SIZE; ++i) { - if (EC_NID_PAIRS[i].key_bit_len_ec == key_bit_len_ec) { - *nid = EC_NID_PAIRS[i].nid; - return YACA_ERROR_NONE; - } - } - - return YACA_ERROR_INVALID_PARAMETER; -} - -size_t convert_nid_to_ec(int nid, size_t *key_bit_len_ec) -{ - assert(key_bit_len_ec != NULL); - - size_t i; - - for (i = 0; i < EC_NID_PAIRS_SIZE; ++i) { - if (EC_NID_PAIRS[i].nid == nid) { - *key_bit_len_ec = EC_NID_PAIRS[i].key_bit_len_ec; - return YACA_ERROR_NONE; - } - } - - return YACA_ERROR_INVALID_PARAMETER; -} - -int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t key_bit_len) +static int generate_evp_pkey_params(int evp_id, size_t key_bit_len, EVP_PKEY **params) { - assert(out != NULL); assert(key_bit_len > 0); + assert(params != NULL); - int id; - bool do_params; int ret; EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY_CTX *kctx = NULL; - EVP_PKEY *pkey = NULL; - EVP_PKEY *params = NULL; - struct yaca_key_evp_s *nk; + int bit_len = 0; + int dh_prime_len = 0; + int dh_generator = 0; + int dh_rfc5114 = 0; + int ec_nid = 0; - switch (key_type) { - case YACA_KEY_TYPE_RSA_PRIV: + switch (evp_id) { + case EVP_PKEY_DSA: if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || - key_bit_len % 8 != 0) + key_bit_len > INT_MAX || key_bit_len < 512 || key_bit_len % 64 != 0) return YACA_ERROR_INVALID_PARAMETER; - id = EVP_PKEY_RSA; - do_params = false; - break; - case YACA_KEY_TYPE_DSA_PRIV: - if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || - /* Openssl generates 512-bit key for key lengths smaller than 512. It also - * rounds key size to multiplication of 64. */ - key_bit_len < 512 || key_bit_len % 64 != 0) - return YACA_ERROR_INVALID_PARAMETER; + bit_len = key_bit_len; - id = EVP_PKEY_DSA; - do_params = true; break; - case YACA_KEY_TYPE_DH_PRIV: - if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || - key_bit_len % 8 != 0) + case EVP_PKEY_DH: + if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) == YACA_INTERNAL_KEYLEN_TYPE_DH) { + size_t gen_block = key_bit_len & YACA_INTERNAL_KEYLEN_DH_GEN_MASK; + size_t prime_len_block = key_bit_len & YACA_INTERNAL_KEYLEN_DH_PRIME_MASK; + + /* This is impossible now as we take only 16 bits, + * but for the sake of type safety */ + if (prime_len_block > INT_MAX) + return YACA_ERROR_INVALID_PARAMETER; + dh_prime_len = prime_len_block; + + if (gen_block == YACA_INTERNAL_KEYLEN_DH_GEN_2) + dh_generator = 2; + else if (gen_block == YACA_INTERNAL_KEYLEN_DH_GEN_5) + dh_generator = 5; + else + return YACA_ERROR_INVALID_PARAMETER; + + } else if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) == YACA_INTERNAL_KEYLEN_TYPE_DH_RFC) { + if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_1024_160) + dh_rfc5114 = 1; /* OpenSSL magic numbers */ + else if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_2048_224) + dh_rfc5114 = 2; + else if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_2048_256) + dh_rfc5114 = 3; + else + return YACA_ERROR_INVALID_PARAMETER; + + } else { return YACA_ERROR_INVALID_PARAMETER; + } - id = EVP_PKEY_DH; - do_params = true; break; - case YACA_KEY_TYPE_EC_PRIV: - if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_EC) - return YACA_ERROR_INVALID_PARAMETER; + case EVP_PKEY_EC: + ret = convert_ec_to_nid(key_bit_len, &ec_nid); + if (ret != YACA_ERROR_NONE) + return ret; - id = EVP_PKEY_EC; - do_params = true; break; default: - return YACA_ERROR_INVALID_PARAMETER; + /* We shouldn't be here */ + assert(false); + return YACA_ERROR_INTERNAL; } - ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk); - if (ret != YACA_ERROR_NONE) - return ret; - - if (do_params) { - pctx = EVP_PKEY_CTX_new_id(id, NULL); - if (pctx == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + pctx = EVP_PKEY_CTX_new_id(evp_id, NULL); + if (pctx == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } - ret = EVP_PKEY_paramgen_init(pctx); - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + ret = EVP_PKEY_paramgen_init(pctx); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } - switch (id) { - case EVP_PKEY_DSA: - ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bit_len); - break; - case EVP_PKEY_DH: - ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, key_bit_len); - break; - case EVP_PKEY_EC: { - int nid; - ret = convert_ec_to_nid(key_bit_len, &nid); - if (ret != YACA_ERROR_NONE) - goto exit; - ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid); + switch (evp_id) { + case EVP_PKEY_DSA: + ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, bit_len); + break; + case EVP_PKEY_DH: + if (dh_rfc5114 > 0) { + /* The following code is based on the macro call below. + * Unfortunately it doesn't work and the suspected reason is the + * fact that the _set_dh_ variant actually passes EVP_PKEY_DHX: + * ret = EVP_PKEY_CTX_set_dh_rfc5114(pctx, dh_rfc5114); */ + ret = EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_RFC5114, dh_rfc5114, NULL); + } else { + ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, dh_prime_len); if (ret == 1) - ret = EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE); - break; - } - default: - /* We shouldn't be here */ - assert(false); - ret = YACA_ERROR_INTERNAL; - goto exit; + ret = EVP_PKEY_CTX_set_dh_paramgen_generator(pctx, dh_generator); } + break; + case EVP_PKEY_EC: + ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ec_nid); + if (ret == 1) + ret = EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE); + break; + } + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } - if (ret != 1) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; - } + ret = EVP_PKEY_paramgen(pctx, params); + if (ret != 1 || params == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } - ret = EVP_PKEY_paramgen(pctx, ¶ms); - if (ret != 1 || params == NULL) { - ret = YACA_ERROR_INTERNAL; - ERROR_DUMP(ret); - goto exit; + ret = YACA_ERROR_NONE; + +exit: + EVP_PKEY_CTX_free(pctx); + return ret; +} + +static int generate_evp_pkey_key(int evp_id, size_t key_bit_len, EVP_PKEY *params, EVP_PKEY **key) +{ + assert(key != NULL); + assert(key_bit_len > 0 || params != NULL); + + int ret; + EVP_PKEY_CTX *kctx = NULL; + + switch (evp_id) { + case EVP_PKEY_RSA: + assert(params == NULL); + kctx = EVP_PKEY_CTX_new_id(evp_id, NULL); + break; + case EVP_PKEY_DSA: + case EVP_PKEY_DH: + case EVP_PKEY_EC: + if (params == NULL) { + ret = generate_evp_pkey_params(evp_id, key_bit_len, ¶ms); + if (ret != YACA_ERROR_NONE) + return ret; + } else { + CRYPTO_add(¶ms->references, 1, CRYPTO_LOCK_EVP_PKEY); } kctx = EVP_PKEY_CTX_new(params, NULL); - } else { - kctx = EVP_PKEY_CTX_new_id(id, NULL); + break; + default: + assert(false); + return YACA_ERROR_INTERNAL; } if (kctx == NULL) { ret = YACA_ERROR_INTERNAL; @@ -985,34 +1032,98 @@ int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t k goto exit; } - if (id == EVP_PKEY_RSA) { - ret = EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, key_bit_len); + if (evp_id == EVP_PKEY_RSA) { + if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS || + key_bit_len > INT_MAX || key_bit_len % 8 != 0) { + ret = YACA_ERROR_INVALID_PARAMETER; + goto exit; + } + + ret = EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, (int)key_bit_len); if (ret != 1) { ret = ERROR_HANDLE(); goto exit; } } - ret = EVP_PKEY_keygen(kctx, &pkey); - if (ret != 1 || pkey == NULL) { + ret = EVP_PKEY_keygen(kctx, key); + if (ret != 1 || key == NULL) { ret = YACA_ERROR_INTERNAL; ERROR_DUMP(ret); goto exit; } - nk->evp = pkey; - pkey = NULL; - *out = nk; - nk = NULL; - ret = YACA_ERROR_NONE; exit: EVP_PKEY_CTX_free(kctx); EVP_PKEY_free(params); - EVP_PKEY_CTX_free(pctx); - yaca_free(nk); + return ret; +} +static int generate_evp(yaca_key_type_e out_type, size_t key_bit_len, + struct yaca_key_evp_s *params, struct yaca_key_evp_s **out) +{ + assert(out != NULL); + assert(key_bit_len > 0 || params != NULL); + + int ret; + int evp_id; + EVP_PKEY *pkey_out = NULL; + EVP_PKEY *pkey_params = NULL; + + if (params != NULL) { + yaca_key_type_e key_type; + yaca_key_type_e params_type = params->key.type; + + ret = convert_params_to_priv(params_type, &key_type); + if (ret != YACA_ERROR_NONE) + return ret; + + if (out_type != key_type) + return YACA_ERROR_INVALID_PARAMETER; + + pkey_params = params->evp; + } + + switch (out_type) { + case YACA_KEY_TYPE_DSA_PARAMS: + case YACA_KEY_TYPE_DH_PARAMS: + case YACA_KEY_TYPE_EC_PARAMS: + assert(params == NULL); + ret = convert_params_to_evp_id(out_type, &evp_id); + if (ret != YACA_ERROR_NONE) + return ret; + + ret = generate_evp_pkey_params(evp_id, key_bit_len, &pkey_out); + break; + case YACA_KEY_TYPE_RSA_PRIV: + case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: + ret = convert_priv_to_evp_id(out_type, &evp_id); + if (ret != YACA_ERROR_NONE) + return ret; + + ret = generate_evp_pkey_key(evp_id, key_bit_len, pkey_params, &pkey_out); + break; + default: + return YACA_ERROR_INVALID_PARAMETER; + } + if (ret != YACA_ERROR_NONE) + return ret; + + ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)out); + if (ret != YACA_ERROR_NONE) + goto exit; + + (*out)->evp = pkey_out; + pkey_out = NULL; + + ret = YACA_ERROR_NONE; + +exit: + EVP_PKEY_free(pkey_out); return ret; } @@ -1052,10 +1163,13 @@ struct yaca_key_evp_s *key_get_evp(const yaca_key_h key) case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DSA_PARAMS: case YACA_KEY_TYPE_DH_PUB: case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_DH_PARAMS: case YACA_KEY_TYPE_EC_PUB: case YACA_KEY_TYPE_EC_PRIV: + case YACA_KEY_TYPE_EC_PARAMS: k = (struct yaca_key_evp_s *)key; /* sanity check */ @@ -1277,9 +1391,12 @@ API int yaca_key_generate(yaca_key_type_e key_type, break; case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DSA_PARAMS: case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_DH_PARAMS: case YACA_KEY_TYPE_EC_PRIV: - ret = generate_evp(&nk_evp, key_type, key_bit_len); + case YACA_KEY_TYPE_EC_PARAMS: + ret = generate_evp(key_type, key_bit_len, NULL, &nk_evp); break; default: return YACA_ERROR_INVALID_PARAMETER; @@ -1294,11 +1411,44 @@ API int yaca_key_generate(yaca_key_type_e key_type, } else if (nk_evp != NULL) { nk_evp->key.type = key_type; *key = (yaca_key_h)nk_evp; + } else { + assert(false); } return YACA_ERROR_NONE; } +API int yaca_key_generate_from_parameters(const yaca_key_h params, yaca_key_h *prv_key) +{ + int ret; + struct yaca_key_evp_s *evp_params = key_get_evp(params); + yaca_key_type_e params_type; + yaca_key_type_e key_type; + struct yaca_key_evp_s *nk_evp = NULL; + + if (evp_params == NULL || prv_key == NULL) + return YACA_ERROR_INVALID_PARAMETER; + + ret = yaca_key_get_type(params, ¶ms_type); + if (ret != YACA_ERROR_NONE) + return ret; + + ret = convert_params_to_priv(params_type, &key_type); + if (ret != YACA_ERROR_NONE) + return ret; + + ret = generate_evp(key_type, 0, evp_params, &nk_evp); + if (ret != YACA_ERROR_NONE) + return ret; + + assert(nk_evp != NULL); + + nk_evp->key.type = key_type; + *prv_key = (yaca_key_h)nk_evp; + + return YACA_ERROR_NONE; +} + API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) { int ret; -- 2.7.4 From 71ab576d08edad73eace8b5656c21aa509513cdd Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 18 Jul 2016 16:11:08 +0200 Subject: [PATCH 14/16] Import/export for EC, DH and all parameter types Change-Id: I4cd1c7c58a64ca78f7fe6c5ce3977c662e69b017 --- src/key.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 204 insertions(+), 59 deletions(-) diff --git a/src/key.c b/src/key.c index ce2008c..12f4e9f 100644 --- a/src/key.c +++ b/src/key.c @@ -91,7 +91,11 @@ static const struct { {EVP_PKEY_RSA, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_TYPE_RSA_PUB, -1}, {EVP_PKEY_DSA, YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_TYPE_DSA_PUB, YACA_KEY_TYPE_DSA_PARAMS}, {EVP_PKEY_DH, YACA_KEY_TYPE_DH_PRIV, YACA_KEY_TYPE_DH_PUB, YACA_KEY_TYPE_DH_PARAMS}, - {EVP_PKEY_EC, YACA_KEY_TYPE_EC_PRIV, YACA_KEY_TYPE_EC_PUB, YACA_KEY_TYPE_EC_PARAMS} + {EVP_PKEY_EC, YACA_KEY_TYPE_EC_PRIV, YACA_KEY_TYPE_EC_PUB, YACA_KEY_TYPE_EC_PARAMS}, + /* The following line is only used to import DHX (RFC5114) keys/params. + * In all other cases DH is used. It has to be below the DH one so conversions from YACA + * internal types are prioritized to EVP_PKEY_DH which is what we want. */ + {EVP_PKEY_DHX, YACA_KEY_TYPE_DH_PRIV, YACA_KEY_TYPE_DH_PUB, YACA_KEY_TYPE_DH_PARAMS} }; static const size_t KEY_TYPES_PARAMS_SIZE = sizeof(KEY_TYPES_PARAMS) / sizeof(KEY_TYPES_PARAMS[0]); @@ -117,6 +121,9 @@ CONVERT_TYPES_TEMPLATE(EC_NID_PAIRS, size_t, ec, int, nid) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, int, evp_id) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, priv, int, evp_id) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, yaca_key_type_e, priv) +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, priv) +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, pub) +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, params) int base64_decode_length(const char *data, size_t data_len, size_t *len) { @@ -304,6 +311,96 @@ exit: return ret; } +static EVP_PKEY *d2i_DSAparams_bio_helper(BIO *src) +{ + assert(src != NULL); + + DSA *dsa = NULL; + EVP_PKEY *pkey = NULL; + + dsa = d2i_DSAparams_bio(src, NULL); + if (dsa == NULL) + return NULL; + + pkey = EVP_PKEY_new(); + if (pkey == NULL) + goto exit; + + if (EVP_PKEY_assign_DSA(pkey, dsa) != 1) + goto exit; + + return pkey; + +exit: + EVP_PKEY_free(pkey); + DSA_free(dsa); + return NULL; +} + +static EVP_PKEY *d2i_DHparams_bio_helper(BIO *src) +{ + assert(src != NULL); + + DH *dh = NULL; + EVP_PKEY *pkey = NULL; + + dh = d2i_DHparams_bio(src, NULL); + if (dh == NULL) + return NULL; + + pkey = EVP_PKEY_new(); + if (pkey == NULL) + goto exit; + + if (EVP_PKEY_assign_DH(pkey, dh) != 1) + goto exit; + + return pkey; + +exit: + EVP_PKEY_free(pkey); + DH_free(dh); + return NULL; +} + +static EVP_PKEY *d2i_ECPKParameters_bio_helper(BIO *src) +{ + assert(src != NULL); + + EC_GROUP *ecg = NULL; + EC_KEY *eck = NULL; + EVP_PKEY *pkey = NULL; + + ecg = d2i_ECPKParameters_bio(src, NULL); + if (ecg == NULL) + return NULL; + + eck = EC_KEY_new(); + if (eck == NULL) + goto exit; + + if (EC_KEY_set_group(eck, ecg) != 1) + goto exit; + + EC_GROUP_free(ecg); + ecg = NULL; + + pkey = EVP_PKEY_new(); + if (pkey == NULL) + goto exit; + + if (EVP_PKEY_assign_EC_KEY(pkey, eck) != 1) + goto exit; + + return pkey; + +exit: + EVP_PKEY_free(pkey); + EC_KEY_free(eck); + EC_GROUP_free(ecg); + return NULL; +} + int import_evp(yaca_key_h *key, yaca_key_type_e key_type, const char *password, @@ -320,9 +417,14 @@ int import_evp(yaca_key_h *key, EVP_PKEY *pkey = NULL; pem_password_cb *cb = openssl_password_cb; struct openssl_password_data cb_data = {false, password}; - bool private; + int imported_evp_id; + enum { + IMPORTED_KEY_CATEGORY_PRIVATE, + IMPORTED_KEY_CATEGORY_PUBLIC, + IMPORTED_KEY_CATEGORY_PARAMETERS + } imported_key_category; + yaca_key_type_e imported_key_type; bool password_supported; - yaca_key_type_e type; struct yaca_key_evp_s *nk = NULL; /* Neither PEM nor DER will ever be shorter then 4 bytes (12 seems @@ -349,7 +451,7 @@ int import_evp(yaca_key_h *key, pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)&cb_data); if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD) return YACA_ERROR_INVALID_PASSWORD; - private = true; + imported_key_category = IMPORTED_KEY_CATEGORY_PRIVATE; password_supported = true; } @@ -357,7 +459,15 @@ int import_evp(yaca_key_h *key, BIO_reset(src); pkey = PEM_read_bio_PUBKEY(src, NULL, openssl_password_cb_error, NULL); ERROR_CLEAR(); - private = false; + imported_key_category = IMPORTED_KEY_CATEGORY_PUBLIC; + password_supported = false; + } + + if (pkey == NULL) { + BIO_reset(src); + pkey = PEM_read_bio_Parameters(src, NULL); + ERROR_CLEAR(); + imported_key_category = IMPORTED_KEY_CATEGORY_PARAMETERS; password_supported = false; } @@ -369,7 +479,7 @@ int import_evp(yaca_key_h *key, X509_free(x509); } ERROR_CLEAR(); - private = false; + imported_key_category = IMPORTED_KEY_CATEGORY_PUBLIC; password_supported = false; } } @@ -380,7 +490,7 @@ int import_evp(yaca_key_h *key, pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)&cb_data); if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD) return YACA_ERROR_INVALID_PASSWORD; - private = true; + imported_key_category = IMPORTED_KEY_CATEGORY_PRIVATE; password_supported = true; } @@ -388,7 +498,7 @@ int import_evp(yaca_key_h *key, BIO_reset(src); pkey = d2i_PrivateKey_bio(src, NULL); ERROR_CLEAR(); - private = true; + imported_key_category = IMPORTED_KEY_CATEGORY_PRIVATE; password_supported = false; } @@ -396,7 +506,31 @@ int import_evp(yaca_key_h *key, BIO_reset(src); pkey = d2i_PUBKEY_bio(src, NULL); ERROR_CLEAR(); - private = false; + imported_key_category = IMPORTED_KEY_CATEGORY_PUBLIC; + password_supported = false; + } + + if (pkey == NULL) { + BIO_reset(src); + pkey = d2i_DSAparams_bio_helper(src); + ERROR_CLEAR(); + imported_key_category = IMPORTED_KEY_CATEGORY_PARAMETERS; + password_supported = false; + } + + if (pkey == NULL) { + BIO_reset(src); + pkey = d2i_DHparams_bio_helper(src); + ERROR_CLEAR(); + imported_key_category = IMPORTED_KEY_CATEGORY_PARAMETERS; + password_supported = false; + } + + if (pkey == NULL) { + BIO_reset(src); + pkey = d2i_ECPKParameters_bio_helper(src); + ERROR_CLEAR(); + imported_key_category = IMPORTED_KEY_CATEGORY_PARAMETERS; password_supported = false; } @@ -408,7 +542,7 @@ int import_evp(yaca_key_h *key, X509_free(x509); } ERROR_CLEAR(); - private = false; + imported_key_category = IMPORTED_KEY_CATEGORY_PUBLIC; password_supported = false; } } @@ -427,25 +561,26 @@ int import_evp(yaca_key_h *key, goto exit; } - switch (EVP_PKEY_type(pkey->type)) { - case EVP_PKEY_RSA: - type = private ? YACA_KEY_TYPE_RSA_PRIV : YACA_KEY_TYPE_RSA_PUB; - break; + imported_evp_id = EVP_PKEY_type(pkey->type); - case EVP_PKEY_DSA: - type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB; + switch (imported_key_category) { + case IMPORTED_KEY_CATEGORY_PRIVATE: + ret = convert_evp_id_to_priv(imported_evp_id, &imported_key_type); break; - - case EVP_PKEY_EC: - type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB; + case IMPORTED_KEY_CATEGORY_PUBLIC: + ret = convert_evp_id_to_pub(imported_evp_id, &imported_key_type); + break; + case IMPORTED_KEY_CATEGORY_PARAMETERS: + ret = convert_evp_id_to_params(imported_evp_id, &imported_key_type); break; - default: - ret = YACA_ERROR_INVALID_PARAMETER; - goto exit; + assert(false); + return YACA_ERROR_INTERNAL; } + if (ret != YACA_ERROR_NONE) + goto exit; - if (type != key_type) { + if (imported_key_type != key_type) { ret = YACA_ERROR_INVALID_PARAMETER; goto exit; } @@ -456,7 +591,7 @@ int import_evp(yaca_key_h *key, nk->evp = pkey; *key = (yaca_key_h)nk; - (*key)->type = type; + (*key)->type = key_type; pkey = NULL; ret = YACA_ERROR_NONE; @@ -578,26 +713,30 @@ int export_evp_default_bio(struct yaca_key_evp_s *evp_key, switch (evp_key->key.type) { case YACA_KEY_TYPE_RSA_PRIV: - ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp), - 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), - enc, NULL, 0, NULL, (void*)password); + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: + ret = PEM_write_bio_PrivateKey(mem, evp_key->evp, enc, + NULL, 0, NULL, (void*)password); break; case YACA_KEY_TYPE_RSA_PUB: case YACA_KEY_TYPE_DSA_PUB: + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_EC_PUB: if (password != NULL) return YACA_ERROR_INVALID_PARAMETER; ret = PEM_write_bio_PUBKEY(mem, evp_key->evp); break; - case YACA_KEY_TYPE_DH_PRIV: - case YACA_KEY_TYPE_DH_PUB: - case YACA_KEY_TYPE_EC_PRIV: - case YACA_KEY_TYPE_EC_PUB: - //TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_DSA_PARAMS: + case YACA_KEY_TYPE_DH_PARAMS: + case YACA_KEY_TYPE_EC_PARAMS: + if (password != NULL) + return YACA_ERROR_INVALID_PARAMETER; + ret = PEM_write_bio_Parameters(mem, evp_key->evp); + break; + default: return YACA_ERROR_INVALID_PARAMETER; } @@ -605,32 +744,39 @@ int export_evp_default_bio(struct yaca_key_evp_s *evp_key, break; case YACA_KEY_FILE_FORMAT_DER: + /* None of the formats in DEFAULT DER support a password */ + if (password != NULL) + return YACA_ERROR_INVALID_PARAMETER; + switch (evp_key->key.type) { case YACA_KEY_TYPE_RSA_PRIV: - if (password != NULL) - return YACA_ERROR_INVALID_PARAMETER; - ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp)); - break; - case YACA_KEY_TYPE_DSA_PRIV: - if (password != NULL) - return YACA_ERROR_INVALID_PARAMETER; - ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp)); + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: + ret = i2d_PrivateKey_bio(mem, evp_key->evp); break; case YACA_KEY_TYPE_RSA_PUB: case YACA_KEY_TYPE_DSA_PUB: - if (password != NULL) - return YACA_ERROR_INVALID_PARAMETER; + case YACA_KEY_TYPE_DH_PUB: + case YACA_KEY_TYPE_EC_PUB: ret = i2d_PUBKEY_bio(mem, evp_key->evp); break; - case YACA_KEY_TYPE_DH_PRIV: - case YACA_KEY_TYPE_DH_PUB: - case YACA_KEY_TYPE_EC_PRIV: - case YACA_KEY_TYPE_EC_PUB: - //TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_DSA_PARAMS: + ret = i2d_DSAparams_bio(mem, EVP_PKEY_get0(evp_key->evp)); + break; + case YACA_KEY_TYPE_DH_PARAMS: + ret = i2d_DHparams_bio(mem, EVP_PKEY_get0(evp_key->evp)); + break; + case YACA_KEY_TYPE_EC_PARAMS: { + const EC_KEY *eck = EVP_PKEY_get0(evp_key->evp); + const EC_GROUP *ecg = EC_KEY_get0_group(eck); + ret = i2d_ECPKParameters_bio(mem, ecg); + break; + } + default: return YACA_ERROR_INVALID_PARAMETER; } @@ -673,14 +819,13 @@ int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key, case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: ret = PEM_write_bio_PKCS8PrivateKey_nid(mem, evp_key->evp, nid, NULL, 0, NULL, (void*)password); break; - case YACA_KEY_TYPE_DH_PRIV: - case YACA_KEY_TYPE_EC_PRIV: - //TODO NOT_IMPLEMENTED + default: - /* Public keys are not supported by PKCS8 */ return YACA_ERROR_INVALID_PARAMETER; } @@ -691,15 +836,13 @@ int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key, case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PRIV: + case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_EC_PRIV: ret = i2d_PKCS8PrivateKey_nid_bio(mem, evp_key->evp, nid, NULL, 0, NULL, (void*)password); break; - case YACA_KEY_TYPE_DH_PRIV: - case YACA_KEY_TYPE_EC_PRIV: - //TODO NOT_IMPLEMENTED default: - /* Public keys are not supported by PKCS8 */ return YACA_ERROR_INVALID_PARAMETER; } @@ -1322,12 +1465,14 @@ API int yaca_key_import(yaca_key_type_e key_type, case YACA_KEY_TYPE_RSA_PRIV: case YACA_KEY_TYPE_DSA_PUB: case YACA_KEY_TYPE_DSA_PRIV: - return import_evp(key, key_type, password, data, data_len); + case YACA_KEY_TYPE_DSA_PARAMS: case YACA_KEY_TYPE_DH_PUB: case YACA_KEY_TYPE_DH_PRIV: + case YACA_KEY_TYPE_DH_PARAMS: case YACA_KEY_TYPE_EC_PUB: case YACA_KEY_TYPE_EC_PRIV: - //TODO NOT_IMPLEMENTED + case YACA_KEY_TYPE_EC_PARAMS: + return import_evp(key, key_type, password, data, data_len); default: return YACA_ERROR_INVALID_PARAMETER; } -- 2.7.4 From 0a33f3d406f63df281af09106d671a90ba517919 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Mon, 18 Jul 2016 16:36:54 +0200 Subject: [PATCH 15/16] yaca_extract_parameters() implementation Also yaca_extract_public() rework to be on par with the above. Change-Id: Iab7d9975809b421d09fe024740d7f29b30b8c82a --- src/key.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 80 insertions(+), 18 deletions(-) diff --git a/src/key.c b/src/key.c index 12f4e9f..f2afec5 100644 --- a/src/key.c +++ b/src/key.c @@ -121,6 +121,9 @@ CONVERT_TYPES_TEMPLATE(EC_NID_PAIRS, size_t, ec, int, nid) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, int, evp_id) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, priv, int, evp_id) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, yaca_key_type_e, priv) +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, priv, yaca_key_type_e, pub) +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, priv, yaca_key_type_e, params) +CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, pub, yaca_key_type_e, params) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, priv) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, pub) CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, params) @@ -1598,13 +1601,23 @@ API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) { int ret; struct yaca_key_evp_s *evp_key = key_get_evp(prv_key); - struct yaca_key_evp_s *nk; + struct yaca_key_evp_s *nk = NULL; + yaca_key_type_e prv_type; + yaca_key_type_e pub_type; BIO *mem = NULL; EVP_PKEY *pkey = NULL; - if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL) + if (evp_key == NULL || pub_key == NULL) return YACA_ERROR_INVALID_PARAMETER; + ret = yaca_key_get_type(prv_key, &prv_type); + if (ret != YACA_ERROR_NONE) + return ret; + + ret = convert_priv_to_pub(prv_type, &pub_type); + if (ret != YACA_ERROR_NONE) + return ret; + ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk); if (ret != YACA_ERROR_NONE) return ret; @@ -1633,27 +1646,76 @@ API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key) BIO_free(mem); mem = NULL; - switch (prv_key->type) { - case YACA_KEY_TYPE_RSA_PRIV: - nk->key.type = YACA_KEY_TYPE_RSA_PUB; - break; - case YACA_KEY_TYPE_DSA_PRIV: - nk->key.type = YACA_KEY_TYPE_DSA_PUB; - break; - case YACA_KEY_TYPE_DH_PRIV: - nk->key.type = YACA_KEY_TYPE_DH_PUB; - break; - case YACA_KEY_TYPE_EC_PRIV: - nk->key.type = YACA_KEY_TYPE_EC_PUB; - break; - default: - ret = YACA_ERROR_INVALID_PARAMETER; + nk->key.type = pub_type; + nk->evp = pkey; + pkey = NULL; + *pub_key = (yaca_key_h)nk; + nk = NULL; + ret = YACA_ERROR_NONE; + +exit: + EVP_PKEY_free(pkey); + BIO_free(mem); + yaca_free(nk); + + return ret; +} + +API int yaca_key_extract_parameters(const yaca_key_h key, yaca_key_h *params) +{ + int ret; + struct yaca_key_evp_s *evp_key = key_get_evp(key); + struct yaca_key_evp_s *nk = NULL; + yaca_key_type_e key_type; + yaca_key_type_e params_type; + BIO *mem = NULL; + EVP_PKEY *pkey = NULL; + + if (evp_key == NULL || params == NULL) + return YACA_ERROR_INVALID_PARAMETER; + + ret = yaca_key_get_type(key, &key_type); + if (ret != YACA_ERROR_NONE) + return ret; + + ret = convert_priv_to_params(key_type, ¶ms_type); + if (ret != YACA_ERROR_NONE) + ret = convert_pub_to_params(key_type, ¶ms_type); + if (ret != YACA_ERROR_NONE) + return ret; + + ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk); + if (ret != YACA_ERROR_NONE) + return ret; + + mem = BIO_new(BIO_s_mem()); + if (mem == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + ret = PEM_write_bio_Parameters(mem, evp_key->evp); + if (ret != 1) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); + goto exit; + } + + pkey = PEM_read_bio_Parameters(mem, NULL); + if (pkey == NULL) { + ret = YACA_ERROR_INTERNAL; + ERROR_DUMP(ret); goto exit; } + BIO_free(mem); + mem = NULL; + + nk->key.type = params_type; nk->evp = pkey; pkey = NULL; - *pub_key = (yaca_key_h)nk; + *params = (yaca_key_h)nk; nk = NULL; ret = YACA_ERROR_NONE; -- 2.7.4 From 360a966dd4d99b4d2476d71857b2983e19a9a5e6 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Wed, 20 Jul 2016 14:20:22 +0200 Subject: [PATCH 16/16] Example for key generate Change-Id: I9230fdc86b738e7ba6c5d7e9ff000bfae1fe830e --- examples/CMakeLists.txt | 1 + examples/key_gen.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 examples/key_gen.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3eae22c..bcc54e4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -48,6 +48,7 @@ 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-gen" key_gen.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) diff --git a/examples/key_gen.c b/examples/key_gen.c new file mode 100644 index 0000000..97ad433 --- /dev/null +++ b/examples/key_gen.c @@ -0,0 +1,126 @@ +/* + * 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 "misc.h" +#include "../src/debug.h" + +int main() +{ + int ret; + yaca_key_h key = YACA_KEY_NULL; + yaca_key_h key_params = YACA_KEY_NULL; + + yaca_debug_set_error_cb(debug_func); + + ret = yaca_initialize(); + if (ret != YACA_ERROR_NONE) + goto error; + + printf("This example doesn't print anything useful unless an error occured.\n" + "It is intended to be looked at only as a code example.\n" + "It might take a long time to execute though due to several keys being generated.\n"); + + /* Regular generation */ + + ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + + ret = yaca_key_generate(YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + + ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + + ret = yaca_key_generate(YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + + ret = yaca_key_generate(YACA_KEY_TYPE_DH_PRIV, YACA_KEY_LENGTH_DH_GENERATOR_2 | 333, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + + ret = yaca_key_generate(YACA_KEY_TYPE_DH_PRIV, YACA_KEY_LENGTH_DH_RFC_2048_224, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + + ret = yaca_key_generate(YACA_KEY_TYPE_EC_PRIV, YACA_KEY_LENGTH_EC_SECP384R1, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + + /* Params + key generation */ + + ret = yaca_key_generate(YACA_KEY_TYPE_DSA_PARAMS, YACA_KEY_LENGTH_512BIT, &key_params); + if (ret != YACA_ERROR_NONE) + goto error; + ret = yaca_key_generate_from_parameters(key_params, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + yaca_key_destroy(key_params); + + ret = yaca_key_generate(YACA_KEY_TYPE_DH_PARAMS, + YACA_KEY_LENGTH_DH_GENERATOR_5 | YACA_KEY_LENGTH_2048BIT, &key_params); + if (ret != YACA_ERROR_NONE) + goto error; + ret = yaca_key_generate_from_parameters(key_params, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + yaca_key_destroy(key_params); + + ret = yaca_key_generate(YACA_KEY_TYPE_DH_PARAMS, YACA_KEY_LENGTH_DH_RFC_2048_256, &key_params); + if (ret != YACA_ERROR_NONE) + goto error; + ret = yaca_key_generate_from_parameters(key_params, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + yaca_key_destroy(key_params); + + ret = yaca_key_generate(YACA_KEY_TYPE_EC_PARAMS, YACA_KEY_LENGTH_EC_PRIME256V1, &key_params); + if (ret != YACA_ERROR_NONE) + goto error; + ret = yaca_key_generate_from_parameters(key_params, &key); + if (ret != YACA_ERROR_NONE) + goto error; + yaca_key_destroy(key); + yaca_key_destroy(key_params); + + return 0; + +error: + printf("Error occured.\n"); + yaca_cleanup(); + + return 1; +} -- 2.7.4