From: Mateusz Kulikowski Date: Thu, 31 Mar 2016 06:25:16 +0000 (+0200) Subject: Library code stub X-Git-Tag: submit/tizen/20160809.225820~257 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=35ca7af835518ff2d0184e2dc7aa7f24e5120d43;p=platform%2Fcore%2Fsecurity%2Fyaca.git Library code stub - Basic symmetric key handling - Simple API - crypto.c: use OPENSSL_alloc/free Addons: - (simple) top-level makefile, makefiles update - Basic error codes - Stubs for all crypto-api functions (all examples are linked properly) - dump_hex() for examples - Moved API headers to api/ top-level-directory - crypto.c: init, rand_bytes, get_output_length - ctx_p.h: stub of context - digest.c: message digest support - key.c: key sanity check, key import (untested), free - simple.c: implementation of simple api (only digest tested) - drop types_p.h Signed-off-by: Mateusz Kulikowski Change-Id: I1438e8466934443afe55bb05eddd7580b9798a6a --- diff --git a/.gitignore b/.gitignore index 2b298c1..6e51bb5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *.d doc/html doc/man +*.a +*.so diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..697bcbc --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +.PHONY: all build clean +all: build + +build: + make -C src + make -C examples + +clean: + make -C src clean + make -C examples clean diff --git a/api/crypto/crypto.h b/api/crypto/crypto.h new file mode 100644 index 0000000..eea2900 --- /dev/null +++ b/api/crypto/crypto.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file crypto.h + * @brief + */ + +#ifndef CRYPTO_H +#define CRYPTO_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Non-Crypto Non crypto related functions. + * + * TODO: extended description and examples. + * + * @{ + */ + +/** + * @brief CRYPTO_CTX_NULL NULL value for the crypto context. + */ +#define CRYPTO_CTX_NULL ((crypto_ctx_h) NULL) + +/** + * @brief crypto_init Initializes the library. Must be called before any other crypto function. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_init(void); + +/** + * @brief crypto_exit Closes the library. Must be called before exiting the application. + * + */ +void crypto_exit(void); + +/** + * @brief crypto_alloc Allocates memory. + * + * @param[in] size Size of the allocation (bytes). + * + * @return NULL on failure, pointer to allocated memory otherwise. + */ +void *crypto_alloc(size_t size); + +/** + * @brief crypto_free Frees the memory allocated by @see crypto_alloc + * or one of the cryptographics operations. + * + * @param[in] ptr Pointer to the memory to be freed. + * + */ +void crypto_free(void *ptr); + +/** + * @brief crypto_rand_bytes Generates random data. + * + * @param[in,out] data Pointer to the memory to be randomized. + * @param[in] data_len Length of the memory to be randomized. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_rand_bytes(char *data, size_t data_len); + +/** + * @brief crypto_ctx_set_param Sets the extended context parameters. + * Can only be called on an initialized context. + * + * @param[in,out] ctx Previously initialized crypto context. + * @param[in] param Parameter to be set. + * @param[in] value Parameter value. + * @param[in] value_len Length of the parameter value. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_ctx_set_param(crypto_ctx_h ctx, crypto_ex_param_e param, + const void *value, size_t value_len); + +/** + * @brief crypto_ctx_get_param Returns the extended context parameters. + * Can only be called on an initialized context. + * + * @param[in] ctx Previously initialized crypto context. + * @param[in] param Parameter to be read. + * @param[out] value Copy of the parameter value (must be freed with @see crypto_free). + * @param[out] value_len Length of the parameter value will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_ctx_get_param(const crypto_ctx_h ctx, crypto_ex_param_e param, + void **value, size_t *value_len); + +/** + * @brief crypto_ctx_free Destroys the crypto context. Must be called + * on all contexts that are no longer used. + * Passing CRYPTO_CTX_NULL is allowed. + * + * @param[in,out] ctx Crypto context. + * + */ +void crypto_ctx_free(crypto_ctx_h ctx); + +/** + * @brief crypto_get_output_length Returns the output length for a given algorithm. + * Can only be called on an initialized context. + * + * @param[in] ctx Previously initialized crypto context. + * @param[in] input_len Length of the input data to be processed. + * + * @return negative on error (@see error.h) or length of output. + */ +int crypto_get_output_length(const crypto_ctx_h ctx, size_t input_len); + +/** + * @brief crypto_get_digest_length Wrapper - returns the length of the digest (for a given context). + */ +#define crypto_get_digest_length(ctxa) crypto_get_output_length((ctxa), 0) + +/** + * @brief crypto_get_sign_length Wrapper - returns the length of the signature (for a given context). + */ +#define crypto_get_sign_length(ctxa) crypto_get_output_length((ctxa), 0) + +/** + * @brief crypto_get_block_length Wrapper - returns the length of the block (for a given context). + */ +#define crypto_get_block_length(ctxa) crypto_get_output_length((ctxa), 0) + +/** + * @brief crypto_get_iv_length Returns the recomended/default length of the IV for a given encryption configuration. + * + * @param[in] algo Encryption algorithm. + * @param[in] bcm Chain mode. + * @param[in] len Key length (@see crypto_key_len_e). + * + * @return negative on error (@see error.h) or the IV length. + */ +int crypto_get_iv_length(crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + size_t key_len); + +/**@}*/ +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* CRYPTO_H */ diff --git a/api/crypto/digest.h b/api/crypto/digest.h new file mode 100644 index 0000000..b9ebafd --- /dev/null +++ b/api/crypto/digest.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file digest.h + * @brief + */ + +#ifndef DIGEST_H +#define DIGEST_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Advanced-Digest Advanced API for the message digests. + * + * TODO: extended description and examples. + * + * @{ + */ + +/** + * @brief crypto_digest_init Initializes a digest context. + * + * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). + * @param[in] algo Digest algorithm that will be used. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_digest_init(crypto_ctx_h *ctx, crypto_digest_algo_e algo); + +/** + * @brief crypto_digest_update Feeds the data into the message digest algorithm. + * + * @param[in,out] ctx Context created by @see crypto_digest_init. + * @param[in] data Data from which the digest is to be calculated. + * @param[in] data_len Length of the data. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_digest_update(crypto_ctx_h ctx, const char *data, size_t data_len); + +/** + * @brief crypto_digest_final Calculates the final digest. + * + * @param[in,out] ctx A valid digest context. + * @param[out] digest Buffer for the message digest (must be allocated by client, @see crypto_get_digest_length). + * @param[out] digest_len Length of the digest, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_digest_final(crypto_ctx_h ctx, char *digest, size_t *digest_len); + +/**@}*/ +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* DIGEST_H */ diff --git a/api/crypto/encrypt.h b/api/crypto/encrypt.h new file mode 100644 index 0000000..eecf3f7 --- /dev/null +++ b/api/crypto/encrypt.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file encrypt.h + * @brief + */ + +#ifndef ENCRYPT_H +#define ENCRYPT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Advanced-Encryption-Symmetric Advanced API for the symmetric encryption. + * + * TODO: extended description and examples. + * + * TODO: Let's describe how to set additional params (like GCM, CCM) + * + * @{ + */ + +/** + * @brief crypto_encrypt_init Initializes an encryption context. + * + * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). + * @param[in] algo Encryption algorithm that will be used. + * @param[in] bcm Chaining mode that will be used. + * @param[in] sym_key Symmetric key that will be used. + * @param[in] iv Initialization vector that will be used. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_encrypt_init(crypto_ctx_h *ctx, + crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv); + +/** + * @brief crypto_encrypt_update Encrypts chunk of the data. + * + * @param[in,out] ctx Context created by @see crypto_encrypt_init. + * @param[in] plain Plain text to be encrypted. + * @param[in] plain_len Length of the plain text. + * @param[out] cipher Buffer for the encrypted data (must be allocated by client, @see crypto_get_output_length). + * @param[out] cipher_len Length of the encrypted data, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_encrypt_update(crypto_ctx_h ctx, + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len); + +/** + * @brief crypto_encrypt_final Encrypts the final chunk of the data. + * + * @param[in,out] ctx A valid encrypt context. + * @param[out] cipher Final piece of the encrypted data (must be allocated by client, @see crypto_get_block_length). + * @param[out] cipher_len Length of the final piece, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_encrypt_final(crypto_ctx_h ctx, + char *cipher, + size_t *cipher_len); + +/** + * @brief crypto_decrypt_init Initializes an decryption context. + * + * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). + * @param[in] algo Encryption algorithm that was used to encrypt the data. + * @param[in] bcm Chaining mode that was used to encrypt the data. + * @param[in] sym_key Symmetric key that was used to encrypt the data. + * @param[in] iv Initialization vector that was used to encrypt the data. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_decrypt_init(crypto_ctx_h *ctx, + crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv); + +/** + * @brief crypto_decrypt_update Decrypts chunk of the data. + * + * @param[in,out] ctx Context created by @see crypto_decrypt_init. + * @param[in] cipher Cipher text to be decrypted. + * @param[in] cipher_len Length of the cipher text. + * @param[out] plain Buffer for the decrypted data (must be allocated by client, @see crypto_get_output_length). + * @param[out] plain_len Length of the decrypted data, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_decrypt_update(crypto_ctx_h ctx, + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len); + +/** + * @brief crypto_decrypt_final Decrypts the final chunk of the data. + * + * @param[in,out] ctx A valid decrypt context. + * @param[out] plain Final piece of the decrypted data (must be allocated by client, @see crypto_get_block_length). + * @param[out] plain_len Length of the final piece, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_decrypt_final(crypto_ctx_h ctx, + char *plain, + size_t *plain_len); + +/**@}*/ + +/** + * @defgroup Advanced-Encryption-Asymmetric Advanced API for the asymmetric encryption. + * + * TODO: extended description and examples. + * + * TODO: Seal does more than just encrypt. It first generates the encryption key and IV, + * then encrypts whole message using this key (and selected symmetric algorithm). + * Finally it encrypts symmetric key with public key. + * + * @{ + */ + +/** + * @brief crypto_seal_init Initializes an asymmetric encryption context. + * + * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). + * @param[in] pub_key Public key of the peer that will receive the encrypted data. + * @param[in] algo Symmetric algorithm that will be used. + * @param[in] bcm Block chaining mode for the symmetric algorithm. + * @param[out] sym_key Generated symmetric key that will be used. It is encrypted with peer's public key. + * @param[out] iv Generated initialization vector that will be used. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_seal_init(crypto_ctx_h *ctx, + const crypto_key_h pub_key, + crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + crypto_key_h *sym_key, + crypto_key_h *iv); + +/** + * @brief crypto_seal_update Encrypts piece of the data. + * + * @param[in,out] ctx Context created by @see crypto_seal_init. + * @param[in] plain Plain text to be encrypted. + * @param[in] plain_len Length of the plain text. + * @param[out] cipher Buffer for the encrypted data (must be allocated by client, @see crypto_get_output_length). + * @param[out] cipher_len Length of the encrypted data, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_seal_update(crypto_ctx_h ctx, + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len); + +/** + * @brief crypto_seal_final Encrypts the final piece of the data. + * + * @param[in,out] ctx A valid seal context. + * @param[out] cipher Final piece of the encrypted data (must be allocated by client, @see crypto_get_block_length). + * @param[out] cipher_len Length of the final piece, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_seal_final(crypto_ctx_h ctx, + char *cipher, + size_t *cipher_len); + +/** + * @brief crypto_open_init Initializes an asymmetric decryption context. + * + * @param[out] ctx Newly created context. Must be freed by @see crypto_ctx_free. + * @param[in] prv_key Private key, part of the pair that was used for the encryption. + * @param[in] algo Symmetric algorithm that was used for the encryption. + * @param[in] bcm Block chaining mode for the symmetric algorithm. + * @param[in] sym_key Symmetric key, encrypted with the public key, that was used to encrypt the data. + * @param[in] iv Initialization vector that was used for the encryption. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_open_init(crypto_ctx_h *ctx, + const crypto_key_h prv_key, + crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv); + +/** + * @brief crypto_open_update Decrypts piece of the data. + * + * @param[in,out] ctx Context created by @see crypto_open_init. + * @param[in] cipher Cipher text to be decrypted. + * @param[in] cipher_len Length of the cipher text. + * @param[out] plain Buffer for the decrypted data (must be allocated by client, @see crypto_get_output_length). + * @param[out] plain_len Length of the decrypted data, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_open_update(crypto_ctx_h ctx, + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len); + +/** + * @brief crypto_open_final Decrypts last chunk of sealed message. + * + * @param[in,out] ctx A valid open context. + * @param[out] plain Final piece of the decrypted data (must be allocated by client, @see crypto_get_block_length). + * @param[out] plain_len Length of the final piece, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_open_final(crypto_ctx_h ctx, + char *plain, + size_t *plain_len); + +/**@}*/ +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* ENCRYPT_H */ diff --git a/api/crypto/error.h b/api/crypto/error.h new file mode 100644 index 0000000..3562add --- /dev/null +++ b/api/crypto/error.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file error.h + * @brief + */ + +#ifndef ERROR_H +#define ERROR_H + +/* + TODO: Error enums should be placed here + */ +#ifdef __cplusplus +extern "C" { +#endif + +enum __crypto_error_code { + CRYPTO_ERROR_INVALID_ARGUMENT = -1, + CRYPTO_ERROR_NOT_IMPLEMENTED= -2, + CRYPTO_ERROR_OPENSSL_FAILURE = -3, + CRYPTO_ERROR_NOT_SUPPORTED = -4, + CRYPTO_ERROR_TOO_BIG_ARGUMENT = -5, + CRYPTO_ERROR_OUT_OF_MEMORY = -6 +}; + +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* ERROR_H */ diff --git a/api/crypto/key.h b/api/crypto/key.h new file mode 100644 index 0000000..34e14c9 --- /dev/null +++ b/api/crypto/key.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file key.h + * @brief + */ + +#ifndef KEY_H +#define KEY_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Key Key and IV handling functions + * + * TODO: extended description and examples. + * + * @{ + */ + +#define CRYPTO_KEY_NULL ((crypto_key_h) NULL) + +// TODO: We need a way to import keys encrypted with hw (or other) keys. New function like crypto_key_load or sth?? + +/** + * @brief crypto_key_get_length Get key's length. + * + * @param[in] key Key which length we return. + * + * @return negative on error (@see error.h) or key length. + */ +int crypto_key_get_length(const crypto_key_h key); + +/** + * @brief crypto_key_import Imports a key from the arbitrary format. + * + * @param[out] key Returned key (must be freed with @see crypto_key_free). + * @param[in] key_fmt Format of the key. + * @param[in] key_type Type of the key. + * @param[in] data Blob containing the key. + * @param[in] data_len Size of the blob. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_key_import(crypto_key_h *key, + crypto_key_fmt_e key_fmt, + crypto_key_type_e key_type, + const char *data, + size_t data_len); + +/** + * @brief crypto_key_export Exports a key to arbitrary format. Export may fail if key is HW-based. + * + * @param[in] key Key to be exported. + * @param[in] key_fmt Format of the key. + * @param[out] data Data, allocated by the library, containing exported key (must be freed with @see crypto_free). + * @param[out] data_len Size of the output data. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_key_export(const crypto_key_h key, + crypto_key_fmt_e key_fmt, + char **data, + size_t *data_len); + +// TODO: still a matter of ordering, should the key in key_gen functions be first or last? + +/** + * @brief crypto_key_gen Generates a secure symmetric key (or an initialization vector). + * + * @param[out] sym_key Newly generated key (must be freed with @see crypto_key_free). + * @param[in] key_type Type of the key to be generated. + * @param[in] key_len Length of the key to be generated. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_key_gen(crypto_key_h *sym_key, + crypto_key_type_e key_type, + size_t key_len); + +/** + * @brief crypto_key_gen_pair Generates a new key pair. + * + * @param[out] prv_key Newly generated private key (must be freed with @see crypto_key_free). + * @param[out] pub_key Newly generated public key (must be freed with @see crypto_key_free). + * @param[in] key_type Type of the key to be generated (must be CRYPTO_KEY_TYPE_PAIR*). + * @param[in] key_len Length of the key to be generated. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_key_gen_pair(crypto_key_h *prv_key, + crypto_key_h *pub_key, + crypto_key_type_e key_type, + size_t key_len); + +/** + * @brief crypto_key_free Frees the key created by the library. + * Passing CRYPTO_KEY_NULL is allowed. + * + * @param key Key to be freed. + * + */ +void crypto_key_free(crypto_key_h key); + +/**@}*/ + +/** + * @defgroup Key-Derivation Key derivation functions + * + * TODO: rethink separate group. + * TODO: extended description and examples. + * + * @{ + */ + +/** + * @brief crypto_key_derive_dh Derives a key using Diffie-Helmann or EC Diffie-Helmann key exchange protocol. + * + * @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 (must be freed with @see crypto_key_free). + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_key_derive_dh(const crypto_key_h prv_key, + const crypto_key_h pub_key, + crypto_key_h *sym_key); + +/** + * @brief crypto_key_derive_kea Derives a key using KEA key exchange protocol. + * + * @param[in] prv_key Our DH private component. + * @param[in] pub_key Peers' DH public component. + * @param[in] prv_key_auth Our private key used to create signature on our + * DH public component sent to peer to verify our identity. + * @param[in] pub_key_auth Peers' public key used for signature verification + * of pub_key from peer (peer authentication). + * @param[out] sym_key Shared secret, that can be used as a symmetric key (must be freed with @see crypto_key_free). + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_key_derive_kea(const crypto_key_h prv_key, + const crypto_key_h pub_key, + const crypto_key_h prv_key_auth, + const crypto_key_h pub_key_auth, + crypto_key_h *sym_key); + +/** + * @brief crypto_key_derive_pbkdf2 Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). + * + * @param[in] password User password as a NULL-terminated string. + * @param[in] salt Salt, should be non-zero. + * @param[in] salt_len Length of the salt. + * @param[in] iter Number of iterations. (TODO: add enum to proposed number of iterations, pick sane defaults). + * @param[in] algo Digest algorithm that should be used in key generation. (TODO: sane defaults). + * @param[in] key_len Length of a key to be generated. + * @param[out] key Newly generated key (must be freed with @see crypto_key_free). + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_key_derive_pbkdf2(const char *password, + const char *salt, + size_t salt_len, + int iter, + crypto_digest_algo_e algo, + crypto_key_len_e key_len, + crypto_key_h *key); + +// TODO: specify +//int crypto_key_wrap(crypto_key_h key, ??); +//int crypto_key_unwrap(crypto_key_h key, ??); + +/**@}*/ +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* KEY_H */ diff --git a/api/crypto/sign.h b/api/crypto/sign.h new file mode 100644 index 0000000..8276fa8 --- /dev/null +++ b/api/crypto/sign.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file sign.h + * @brief + */ + +#ifndef SIGN_H +#define SIGN_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Advanced-Integrity Advanced API for the integrity handling - HMAC, CMAC and digital signature. + * + * TODO: extended description and examples. + * TODO: add documentation how to set padding etc + * + * @{ + */ + +/** + * @brief crypto_sign_init Initializes a signature context. + * + * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). + * @param[in] algo Digest algorithm that will be used. + * @param[in] key Private or symmetric key that will be used (algorithm is deduced based on key type). + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_sign_init(crypto_ctx_h *ctx, + crypto_digest_algo_e algo, + const crypto_key_h key); + +/** + * @brief crypto_sign_update Feeds the data into the digital signature algorithm. + * + * @param[in,out] ctx Context created by @see crypto_sign_init. + * @param[in] data Data to be signed. + * @param[in] data_len Length of the data. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_sign_update(crypto_ctx_h ctx, + const char *data, + size_t data_len); + +/** + * @brief crypto_sign_final Calculates the final signature. + * + * @param[in,out] ctx A valid sign context. + * @param[out] mac Buffer for the MAC or the signature (must be allocated by client, @see crypto_get_sign_length). + * @param[out] mac_len Length of the MAC or the signature, actual number of bytes written will be returned here. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_sign_final(crypto_ctx_h ctx, + char *mac, + size_t *mac_len); + +/** + * @brief crypto_verify_init Initializes a signature verification context. + * + * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). + * @param[in] algo Digest algorithm that will be used. + * @param[in] key Private or symmetric key that will be used (algorithm is deduced based on key type). + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_verify_init(crypto_ctx_h *ctx, + crypto_digest_algo_e algo, + const crypto_key_h key); + +/** + * @brief crypto_verify_update Feeds the data into the digital signature verification algorithm. + * + * @param[in,out] ctx Context created by @see crypto_verify_init. + * @param[in] data Data to be verified. + * @param[in] data_len Length of the data. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_verify_update(crypto_ctx_h ctx, + const char *data, + size_t data_len); + +/** + * @brief crypto_verify_final Performs the verification. + * + * @param[in,out] ctx A valid verify context. + * @param[in] mac Input MAC or signature (returned by @see crypto_sign_final). + * @param[in] mac_len Size of the MAC or the signature. + * + * @return 0 on success, negative on error (@see error.h). + * TODO: CRYTPO_ERROR_SIGNATURE_INVALID when verification fails. + */ +int crypto_verify_final(crypto_ctx_h ctx, + const char *mac, + size_t mac_len); + +/**@}*/ +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* SIGN_H */ diff --git a/api/crypto/simple.h b/api/crypto/simple.h new file mode 100644 index 0000000..5d0ca8a --- /dev/null +++ b/api/crypto/simple.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file simple.h + * @brief + */ + +#ifndef SIMPLE_H +#define SIMPLE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Simple-API Simple API. + * + * 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 chaining is not supported + * - All outputs are allocated by the library + * + * TODO: extended description and examples. + * + * @{ + */ + +/** + * @brief crypto_digest_calc Calculate a digest of a buffer. + * + * @param[in] algo Digest algorithm (select @see CRYPTO_DIGEST_SHA256 if unsure). + * @param[in] data Data from which the digest is to be calculated. + * @param[in] data_len Length of the data. + * @param[out] digest Message digest, will be allocated by the library (should be freed with @see crypto_free). + * @param[out] digest_len Length of message digest (depends on algorithm). + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_digest_calc(crypto_digest_algo_e algo, + const char *data, + size_t data_len, + char **digest, + size_t *digest_len); + +/** + * @brief crypto_encrypt Encrypt data using a symmetric cipher. + * + * @param[in] algo Encryption algorithm (select @see CRYPTO_ENC_AES if unsure). + * @param[in] bcm Chaining mode (select @see CRYPTO_BCM_CBC if unsure). + * @param[in] sym_key Symmetric encryption key (@see key.h for key generation functions). + * @param[in] iv Initialization vector. + * @param[in] plain Plain text to be encrypted. + * @param[in] plain_len Length of the plain text. + * @param[out] cipher Encrypted data, will be allocated by the library (should be freed with @see crypto_free). + * @param[out] cipher_len Length of the encrypted data (may be larger than decrypted). + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_encrypt(crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv, + const char *plain, + size_t plain_len, + char **cipher, + size_t *cipher_len); + +/** + * @brief crypto_decrypt Decrypta data using a symmetric cipher. + * + * @param[in] algo Decryption algorithm that was used to encrypt the data. + * @param[in] bcm Chaining mode that was used to encrypt the data. + * @param[in] sym_key Symmetric encryption key that was used to encrypt the data. + * @param[in] iv Initialization vector that was used to encrypt the data. + * @param[in] cipher Cipher text to be decrypted. + * @param[in] cipher_len Length of cipher text. + * @param[out] plain Decrypted data, will be allocated by the library (should be freed with @see crypto_free). + * @param[out] plain_len Length of the decrypted data. + * + * @return 0 on success, negative on error (@see error.h). + */ +int crypto_decrypt(crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv, + const char *cipher, + size_t cipher_len, + char **plain, + size_t * plain_len); + +// TODO: sign/verify + +/**@}*/ +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* SIMPLE_H */ diff --git a/api/crypto/types.h b/api/crypto/types.h new file mode 100644 index 0000000..c74c4a3 --- /dev/null +++ b/api/crypto/types.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file types.h + * @brief + */ + +#ifndef TYPES_H +#define TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Crypto-Types Enumerations for CryptoAPI + * + * TODO: extended description. + * + * @{ + */ + +/** + * @brief Context + */ +typedef struct __crypto_ctx_s *crypto_ctx_h; + +/** + * @brief Key + */ +typedef struct __crypto_key_s *crypto_key_h; + +/** + * @brief Key formats + */ +typedef enum { + CRYPTO_KEY_FORMAT_RAW, /**< key is in clear format */ + CRYPTO_KEY_FORMAT_BASE64, /**< key is encoded in ASCII-base64 */ + CRYPTO_KEY_FORMAT_PEM, /**< key is in PEM file format */ + CRYPTO_KEY_FORMAT_DER /**< key is in DER file format */ +} crypto_key_fmt_e; + +/** + * @brief Key types, IV is considered as key + */ +typedef enum { + CRYPTO_KEY_TYPE_SYMMETRIC, /**< Generic symmetric cipher KEY */ + CRYPTO_KEY_TYPE_DES, /**< DES* key - must be handled differently because of parity bits */ + CRYPTO_KEY_TYPE_IV, /**< IV for symmetric algorithms */ + + CRYPTO_KEY_TYPE_RSA_PUB, /**< RSA public key */ + CRYPTO_KEY_TYPE_RSA_PRIV, /**< RSA private key */ + + CRYPTO_KEY_TYPE_DSA_PUB, /**< DSA public key */ + CRYPTO_KEY_TYPE_DSA_PRIV, /**< DSA private key */ + + CRYPTO_KEY_TYPE_DH_PUB, /**< Diffie-Hellman public key */ + CRYPTO_KEY_TYPE_DH_PRIV, /**< Diffie-Hellman private key */ + + CRYPTO_KEY_TYPE_ECC_PUB, /**< ECC public key */ + CRYPTO_KEY_TYPE_ECC_PRIV, /**< ECC private key */ + + CRYPTO_KEY_TYPE_PAIR_RSA, /**< Pair of RSA keys */ + CRYPTO_KEY_TYPE_PAIR_DSA, /**< Pair of DSA keys */ + CRYPTO_KEY_TYPE_PAIR_DH, /**< Pair of Diffie-Hellman keys */ + CRYPTO_KEY_TYPE_PAIR_ECC /**< Pair of ECC keys */ +} crypto_key_type_e; + +/** + * @brief Key length, It is possible to use arbitrary integer instead, this enums are placed here to avoid magic numbers. + */ +typedef enum { + CRYPTO_KEY_IV_UNSAFE_24BIT = 24, /**< 24-bit IV */ + CRYPTO_KEY_IV_64BIT = 64, /**< 64-bit IV */ + CRYPTO_KEY_IV_128BIT = 128, /**< 128-bit IV */ + CRYPTO_KEY_IV_256BIT = 256, /**< 256-bit IV */ + CRYPTO_KEY_CURVE_P192 = 192, /**< ECC: P192 curve */ + CRYPTO_KEY_CURVE_P256 = 256, /**< ECC: P-256 curve */ + CRYPTO_KEY_CURVE_P384 = 384, /**< ECC: SECP-384 curve */ + CRYPTO_KEY_UNSAFE_40BIT = 40, + CRYPTO_KEY_UNSAFE_56BIT = 56, + CRYPTO_KEY_UNSAFE_80BIT = 80, + CRYPTO_KEY_UNSAFE_112BIT = 112, + CRYPTO_KEY_UNSAFE_128BIT = 128, + CRYPTO_KEY_192BIT = 192, + CRYPTO_KEY_256BIT = 256, + CRYPTO_KEY_512BIT = 512, + CRYPTO_KEY_1024BIT = 1024, + CRYPTO_KEY_2048BIT = 2048, + CRYPTO_KEY_3072BIT = 3072, + CRYPTO_KEY_4096BIT = 4096 +} crypto_key_len_e; + +/** + * @brief Message digest algorithms. CMAC is included to simplify API + */ +typedef enum { + CRYPTO_DIGEST_MD5, /**< Message digest algorithm MD5 */ + CRYPTO_DIGEST_SHA1, /**< Message digest algorithm SHA1 */ + CRYPTO_DIGEST_SHA224, /**< Message digest algorithm SHA2, 224bit */ + CRYPTO_DIGEST_SHA256, /**< Message digest algorithm SHA2, 256bit */ + CRYPTO_DIGEST_SHA384, /**< Message digest algorithm SHA2, 384bit */ + CRYPTO_DIGEST_SHA512, /**< Message digest algorithm SHA2, 512bit */ + CRYPTO_DIGEST_CMAC /**< TODO: perhaps CMAC should be handled differently */ +} crypto_digest_algo_e; + +/** + * @brief Symmetric encryption algorithms + */ +typedef enum { + CRYPTO_ENC_AES = 0, /**< AES encryption. + - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) + Supported key lengths: @c 128, @c 192 and @c 256 */ + + CRYPTO_ENC_UNSAFE_DES, /**< DES encryption. + - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) + Supported key lengths: @c 56 */ + + CRYPTO_ENC_UNSAFE_3DES_2TDEA, /**< 3DES 2-key encryption. + - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) + Use double DES keys to perform corresponding 2-key 3DES encryption. Supported key lengths: @c 112 */ + + CRYPTO_ENC_3DES_3TDEA, /**< 3DES 3-key encryption. + - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) + Use triple DES keys to perform corresponding 3-key 3DES encryption. Supported key lengths: @c 168 */ + + CRYPTO_ENC_UNSAFE_RC2, /**< RC2 encryption. + - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) + The key length is extracted from the key buffer. Supported key lengths: 8-1024 bits in steps of 8 bits. */ + + CRYPTO_ENC_UNSAFE_RC4, /**< RC4 encryption. + The key length is extracted from the key buffer. Supported key lengths: 40–2048 bits in steps of 8 bits */ + + CRYPTO_ENC_CAST5, /**< CAST5 encryption. + - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) + The key length is extracted from the key buffer. Supported key lengths: 40-128 bits in steps of 8 bits */ + + CRYPTO_ENC_UNSAFE_SKIPJACK /**< SKIPJACK algorithm + - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) + Supported key length: 80 bits */ +} crypto_enc_algo_e; + +/** + * @brief Chaining modes for block ciphers + */ +typedef enum { + CRYPTO_BCM_ECB, /**< ECB block cipher mode. Encrypts 64 bit at a time. No IV is used. */ + + CRYPTO_BCM_CTR, /**< CTR block cipher mode. 16-byte initialization vector is mandatory. + Supported parameters: + - CRYPTO_PARAM_CTR_CNT = length of counter block in bits + (optional, only 128b is supported at the moment) */ + + CRYPTO_BCM_CBC, /**< CBC block cipher mode. 16-byte initialization vector is mandatory. */ + + CRYPTO_BCM_GCM, /**< GCM block cipher mode. IV is needed. + Supported parameters: + - CRYPTO_PARAM_TAG = GCM tag + - CRYPTO_PARAM_AAD = additional authentication data(optional) */ + + CRYPTO_BCM_CFB, /**< CFB block cipher mode. 16-byte initialization vector is mandatory. */ + + CRYPTO_BCM_OFB, /**< OFB block cipher mode. 16-byte initialization vector is mandatory. */ + + CRYPTO_BCM_OCB, /**< Offest Codebook Mode (AES) */ + + CRYPTO_BCM_CCM /**< CBC-MAC Mode (AES) */ + +} crypto_block_cipher_mode_e; + + +/** + * @brief Non-standard parameters for algorithms + */ +typedef enum { + CRYPTO_PARAM_PADDING, /**< Padding */ + + CRYPTO_PARAM_CTR_CNT, /**< CTR Counter bits */ + + CRYPTO_PARAM_GCM_AAD, /**< GCM Additional Authentication Data */ + CRYPTO_PARAM_GCM_TAG, /**< GCM Tag bits */ + CRYPTO_PARAM_GCM_TAG_LEN, /**< GCM Tag length */ + + CRYPTO_PARAM_CCM_AAD, /**< CCM Additional Authentication Data */ + CRYPTO_PARAM_CCM_TAG, /**< CCM Tag bits */ + CRYPTO_PARAM_CCM_TAG_LEN, /**< CCM Tag length */ +} crypto_ex_param_e; + +/** + * @brief Paddings supported by CryptoAPI + */ +typedef enum { + CRYPTO_PADDING_NONE = 0, /**< total number of data MUST multiple of block size, Default */ + CRYPTO_PADDING_ZEROS, /**< pad with zeros */ + CRYPTO_PADDING_ISO10126, /**< ISO 10126 */ + CRYPTO_PADDING_ANSIX923, /**< ANSI X.923 padding*/ + CRYPTO_PADDING_ANSIX931, /**< ANSI X.931 padding*/ + CRYPTO_PADDING_PKCS1, /**< RSA signature creation */ + CRYPTO_PADDING_PKCS7 /**< Byte padding for symetric algos (RFC 5652), (PKCS5 padding is the same) */ +} crypto_padding_e; + +/**@}*/ +#ifdef __cplusplus +} /* extern */ +#endif + +#endif /* TYPES_H */ diff --git a/examples/Makefile b/examples/Makefile index 99afb2b..b1c828a 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,16 +1,36 @@ # Sample makefile - for now it only checks if sources compile -files := $(basename $(wildcard *.c)) -objs := $(addsuffix .o, $(files)) -deps := $(addsuffix .d, $(files)) + +# Disable implicit rules +.SUFFIXES: + +# keep objects +.PRECIOUS: %.o + +examples := digest.c encrypt.c encrypt_aes_gcm.c key_exchange.c sign.c test.c + +bins := $(basename $(examples)) +objs := $(addsuffix .o, $(bins)) +deps := $(addsuffix .d, $(bins)) + +common-objs := misc.o lorem.o +common-deps := misc.d lorem.d + +LDFLAGS := -L../src +LIBS:= -lCryptoAPI $(shell pkg-config --libs openssl) +CFLAGS := $(shell pkg-config --cflags openssl) -I../api -Wall -MMD all: build -build: $(objs) +build: $(bins) + +%: %.o $(common-objs) + gcc $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ + +clean: + rm -f $(objs) $(deps) $(bins) $(common-objs) $(common-deps) -clean: - rm -f $(objs) $(deps) %.o: %.c - gcc -I../src/include -MMD -Wall -c $< -o $@ + gcc $(CFLAGS) -c $< -o $@ -include $(deps) diff --git a/examples/misc.c b/examples/misc.c new file mode 100644 index 0000000..e5c76d3 --- /dev/null +++ b/examples/misc.c @@ -0,0 +1,15 @@ +#include +#include + +#include +#include "misc.h" + +void dump_hex(const char *buf, size_t dump_size, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + BIO_dump_fp(stdout, buf, dump_size); +} diff --git a/examples/test.c b/examples/test.c new file mode 100644 index 0000000..68fef4b --- /dev/null +++ b/examples/test.c @@ -0,0 +1,24 @@ +#include +#include +#include + +#include "misc.h" + +/** Simple test for development of library (before API is ready) */ + +int main(int argc, char* argv[]) +{ + crypto_key_h key; + char *k; + size_t kl; + int ret; + + printf("Generating key using CryptoAPI.. "); + ret = crypto_key_gen(&key, CRYPTO_KEY_TYPE_SYMMETRIC, CRYPTO_KEY_UNSAFE_128BIT); + printf("done (%d)\n", ret); + printf("Exporting key using CryptoAPI.. "); + ret = crypto_key_export(key, CRYPTO_KEY_FORMAT_RAW, &k, &kl); + printf("done (%d)\n", ret); + dump_hex(k, kl, "%zu-bit key: \n", kl); + return 0; +} diff --git a/readme.txt b/readme.txt index 5ff47f7..19ac4ad 100644 --- a/readme.txt +++ b/readme.txt @@ -7,12 +7,13 @@ Code Style (for now): $ astyle -T8 Project structure: + api/ - Public API (headers) + demos/ - Demo applications doc/ - Documentation examples/ - Usage examples src/ - source - src/include/crypto - headers test/ - tests diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..1cabda1 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,28 @@ +# Sample makefile - for now it only checks if sources compile +files := $(basename $(wildcard *.c)) +objs := $(addsuffix .o, $(files)) +deps := $(addsuffix .d, $(files)) + +libs := libCryptoAPI.so libCryptoAPI.a + +LIBS := $(shell pkg-config --libs openssl) +CFLAGS := $(shell pkg-config --cflags openssl) -I../api -Wall -MMD -fPIC + +.PHONY: all build clean +all: build + +build: $(libs) + +clean: + rm -f $(objs) $(deps) $(libs) + +%.so: $(objs) + gcc $(LDFLAGS) $^ $(LIBS) -shared -o $@ + +%.a: $(objs) + ar rcs $@ $< + +%.o: %.c + gcc $(CFLAGS) -c $< -o $@ + +-include $(deps) diff --git a/src/crypto.c b/src/crypto.c new file mode 100644 index 0000000..5eda510 --- /dev/null +++ b/src/crypto.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#include + +#include +#include +#include + +#include +#include + +#include "ctx_p.h" + +int crypto_init(void) +{ + OPENSSL_init(); + OpenSSL_add_all_digests(); + OpenSSL_add_all_ciphers(); + return 0; +} + +void crypto_exit(void) +{ +} + +void *crypto_alloc(size_t size) +{ + return OPENSSL_malloc(size); +} + +void crypto_free(void *ptr) +{ + OPENSSL_free(ptr); +} + +int crypto_rand_bytes(char *data, size_t data_len) +{ + int ret; + + if (!data || data_len == 0) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + ret = RAND_bytes((unsigned char *)data, data_len); + if (ret == -1) + return CRYPTO_ERROR_NOT_SUPPORTED; + if (ret == 1) + return 0; + + return CRYPTO_ERROR_OPENSSL_FAILURE; +} + +int crypto_ctx_set_param(crypto_ctx_h ctx, crypto_ex_param_e param, + const void *value, size_t value_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_ctx_get_param(const crypto_ctx_h ctx, crypto_ex_param_e param, + void **value, size_t *value_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +void crypto_ctx_free(crypto_ctx_h ctx) +{ + crypto_free(ctx); +} + +int crypto_get_output_length(const crypto_ctx_h ctx, size_t input_len) +{ + if (!ctx) + return CRYPTO_ERROR_INVALID_ARGUMENT; + return ctx->get_output_length(ctx, input_len); +} + +int crypto_get_iv_length(crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + size_t key_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} diff --git a/src/ctx_p.h b/src/ctx_p.h new file mode 100644 index 0000000..39882fe --- /dev/null +++ b/src/ctx_p.h @@ -0,0 +1,39 @@ +/* + * 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 + */ + +#ifndef CTX_P_H +#define CTX_P_H + +#include +#include + +enum __crypto_ctx_type { + CRYPTO_CTX_INVALID = 0, + CRYPTO_CTX_DIGEST +}; + +/* Base structure for crypto contexts - to be inherited */ +struct __crypto_ctx_s +{ + enum __crypto_ctx_type type; + + int (*get_output_length)(const crypto_ctx_h ctx, size_t input_len); +}; + +#endif // CTX_P_H + diff --git a/src/digest.c b/src/digest.c new file mode 100644 index 0000000..050d346 --- /dev/null +++ b/src/digest.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#include +#include + +#include +#include + +#include +#include + +#include "ctx_p.h" + +typedef struct __crypto_digest_ctx { + struct __crypto_ctx_s ctx; + + const EVP_MD *md; + EVP_MD_CTX *mdctx; +} crypto_digest_ctx; + +static crypto_digest_ctx *get_ctx(crypto_ctx_h ctx) +{ + if (!ctx) + return NULL; + if (ctx->type != CRYPTO_CTX_DIGEST) + return NULL; + return (crypto_digest_ctx *)ctx; +} + +static int get_digest_output_length(const crypto_ctx_h ctx, size_t input_len) +{ + crypto_digest_ctx *c = get_ctx(ctx); + + if (!c) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + return EVP_MD_size(c->md); +} + + +int crypto_digest_init(crypto_ctx_h *ctx, crypto_digest_algo_e algo) +{ + crypto_digest_ctx *nc; + int ret; + + if (!ctx) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + nc = crypto_alloc(sizeof(struct __crypto_digest_ctx)); + if (!nc) + return CRYPTO_ERROR_OUT_OF_MEMORY; + + nc->ctx.type = CRYPTO_CTX_DIGEST; + nc->ctx.get_output_length = get_digest_output_length; + + switch (algo) + { + case CRYPTO_DIGEST_MD5: + nc->md = EVP_md5(); + break; + case CRYPTO_DIGEST_SHA1: + nc->md = EVP_sha1(); + break; + case CRYPTO_DIGEST_SHA224: + nc->md = EVP_sha224(); + break; + case CRYPTO_DIGEST_SHA256: + nc->md = EVP_sha256(); + break; + case CRYPTO_DIGEST_SHA384: + nc->md = EVP_sha384(); + break; + case CRYPTO_DIGEST_SHA512: + nc->md = EVP_sha512(); + break; + default: + crypto_free(nc); + return CRYPTO_ERROR_INVALID_ARGUMENT; + } + + if (!nc->md) { + crypto_free(nc); + return CRYPTO_ERROR_OPENSSL_FAILURE; + } + + nc->mdctx = EVP_MD_CTX_create(); + if (!nc->mdctx) { + crypto_free(nc); + return CRYPTO_ERROR_OPENSSL_FAILURE; + } + + ret = EVP_DigestInit(nc->mdctx, nc->md); + if (ret == 1) { + *ctx = &nc->ctx; //TODO: how to do it "better" ? + return 0; + } + + EVP_MD_CTX_destroy(nc->mdctx); + crypto_free(nc); + + return CRYPTO_ERROR_OPENSSL_FAILURE; +} + +int crypto_digest_update(crypto_ctx_h ctx, const char *data, size_t data_len) +{ + crypto_digest_ctx *c = get_ctx(ctx); + int ret; + + if (!c || !data || !data_len) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + ret = EVP_DigestUpdate(c->mdctx, data, data_len); + + if (ret == 1) + return 0; + + return CRYPTO_ERROR_OPENSSL_FAILURE; +} + +int crypto_digest_final(crypto_ctx_h ctx, char *digest, size_t *digest_len) +{ + crypto_digest_ctx *c = get_ctx(ctx); + int ret; + unsigned len = 0; + + if (!c || !digest || !digest_len) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + if (*digest_len == 0 || *digest_len > UINT_MAX) // DigestFinal accepts uint + return CRYPTO_ERROR_INVALID_ARGUMENT; + + ret = EVP_DigestFinal_ex(c->mdctx, (unsigned char*)digest, &len); + *digest_len = len; + if (ret == 1) + return 0; + + return CRYPTO_ERROR_OPENSSL_FAILURE; +} diff --git a/src/encrypt.c b/src/encrypt.c new file mode 100644 index 0000000..764256d --- /dev/null +++ b/src/encrypt.c @@ -0,0 +1,127 @@ +/* + * 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 + +int crypto_encrypt_init(crypto_ctx_h *ctx, + crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_encrypt_update(crypto_ctx_h ctx, + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_encrypt_final(crypto_ctx_h ctx, + char *cipher, + size_t *cipher_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_decrypt_init(crypto_ctx_h *ctx, + crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_decrypt_update(crypto_ctx_h ctx, + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_decrypt_final(crypto_ctx_h ctx, + char *plain, + size_t *plain_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_seal_init(crypto_ctx_h *ctx, + const crypto_key_h pub_key, + crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + crypto_key_h *sym_key, + crypto_key_h *iv) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_seal_update(crypto_ctx_h ctx, + const char *plain, + size_t plain_len, + char *cipher, + size_t *cipher_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_seal_final(crypto_ctx_h ctx, + char *cipher, + size_t *cipher_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_open_init(crypto_ctx_h *ctx, + const crypto_key_h prv_key, + crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_open_update(crypto_ctx_h ctx, + const char *cipher, + size_t cipher_len, + char *plain, + size_t *plain_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_open_final(crypto_ctx_h ctx, + char *plain, + size_t *plain_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} diff --git a/src/include/crypto/crypto.h b/src/include/crypto/crypto.h deleted file mode 100644 index eea2900..0000000 --- a/src/include/crypto/crypto.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file crypto.h - * @brief - */ - -#ifndef CRYPTO_H -#define CRYPTO_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup Non-Crypto Non crypto related functions. - * - * TODO: extended description and examples. - * - * @{ - */ - -/** - * @brief CRYPTO_CTX_NULL NULL value for the crypto context. - */ -#define CRYPTO_CTX_NULL ((crypto_ctx_h) NULL) - -/** - * @brief crypto_init Initializes the library. Must be called before any other crypto function. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_init(void); - -/** - * @brief crypto_exit Closes the library. Must be called before exiting the application. - * - */ -void crypto_exit(void); - -/** - * @brief crypto_alloc Allocates memory. - * - * @param[in] size Size of the allocation (bytes). - * - * @return NULL on failure, pointer to allocated memory otherwise. - */ -void *crypto_alloc(size_t size); - -/** - * @brief crypto_free Frees the memory allocated by @see crypto_alloc - * or one of the cryptographics operations. - * - * @param[in] ptr Pointer to the memory to be freed. - * - */ -void crypto_free(void *ptr); - -/** - * @brief crypto_rand_bytes Generates random data. - * - * @param[in,out] data Pointer to the memory to be randomized. - * @param[in] data_len Length of the memory to be randomized. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_rand_bytes(char *data, size_t data_len); - -/** - * @brief crypto_ctx_set_param Sets the extended context parameters. - * Can only be called on an initialized context. - * - * @param[in,out] ctx Previously initialized crypto context. - * @param[in] param Parameter to be set. - * @param[in] value Parameter value. - * @param[in] value_len Length of the parameter value. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_ctx_set_param(crypto_ctx_h ctx, crypto_ex_param_e param, - const void *value, size_t value_len); - -/** - * @brief crypto_ctx_get_param Returns the extended context parameters. - * Can only be called on an initialized context. - * - * @param[in] ctx Previously initialized crypto context. - * @param[in] param Parameter to be read. - * @param[out] value Copy of the parameter value (must be freed with @see crypto_free). - * @param[out] value_len Length of the parameter value will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_ctx_get_param(const crypto_ctx_h ctx, crypto_ex_param_e param, - void **value, size_t *value_len); - -/** - * @brief crypto_ctx_free Destroys the crypto context. Must be called - * on all contexts that are no longer used. - * Passing CRYPTO_CTX_NULL is allowed. - * - * @param[in,out] ctx Crypto context. - * - */ -void crypto_ctx_free(crypto_ctx_h ctx); - -/** - * @brief crypto_get_output_length Returns the output length for a given algorithm. - * Can only be called on an initialized context. - * - * @param[in] ctx Previously initialized crypto context. - * @param[in] input_len Length of the input data to be processed. - * - * @return negative on error (@see error.h) or length of output. - */ -int crypto_get_output_length(const crypto_ctx_h ctx, size_t input_len); - -/** - * @brief crypto_get_digest_length Wrapper - returns the length of the digest (for a given context). - */ -#define crypto_get_digest_length(ctxa) crypto_get_output_length((ctxa), 0) - -/** - * @brief crypto_get_sign_length Wrapper - returns the length of the signature (for a given context). - */ -#define crypto_get_sign_length(ctxa) crypto_get_output_length((ctxa), 0) - -/** - * @brief crypto_get_block_length Wrapper - returns the length of the block (for a given context). - */ -#define crypto_get_block_length(ctxa) crypto_get_output_length((ctxa), 0) - -/** - * @brief crypto_get_iv_length Returns the recomended/default length of the IV for a given encryption configuration. - * - * @param[in] algo Encryption algorithm. - * @param[in] bcm Chain mode. - * @param[in] len Key length (@see crypto_key_len_e). - * - * @return negative on error (@see error.h) or the IV length. - */ -int crypto_get_iv_length(crypto_enc_algo_e algo, - crypto_block_cipher_mode_e bcm, - size_t key_len); - -/**@}*/ -#ifdef __cplusplus -} /* extern */ -#endif - -#endif /* CRYPTO_H */ diff --git a/src/include/crypto/digest.h b/src/include/crypto/digest.h deleted file mode 100644 index b9ebafd..0000000 --- a/src/include/crypto/digest.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file digest.h - * @brief - */ - -#ifndef DIGEST_H -#define DIGEST_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup Advanced-Digest Advanced API for the message digests. - * - * TODO: extended description and examples. - * - * @{ - */ - -/** - * @brief crypto_digest_init Initializes a digest context. - * - * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). - * @param[in] algo Digest algorithm that will be used. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_digest_init(crypto_ctx_h *ctx, crypto_digest_algo_e algo); - -/** - * @brief crypto_digest_update Feeds the data into the message digest algorithm. - * - * @param[in,out] ctx Context created by @see crypto_digest_init. - * @param[in] data Data from which the digest is to be calculated. - * @param[in] data_len Length of the data. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_digest_update(crypto_ctx_h ctx, const char *data, size_t data_len); - -/** - * @brief crypto_digest_final Calculates the final digest. - * - * @param[in,out] ctx A valid digest context. - * @param[out] digest Buffer for the message digest (must be allocated by client, @see crypto_get_digest_length). - * @param[out] digest_len Length of the digest, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_digest_final(crypto_ctx_h ctx, char *digest, size_t *digest_len); - -/**@}*/ -#ifdef __cplusplus -} /* extern */ -#endif - -#endif /* DIGEST_H */ diff --git a/src/include/crypto/encrypt.h b/src/include/crypto/encrypt.h deleted file mode 100644 index eecf3f7..0000000 --- a/src/include/crypto/encrypt.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file encrypt.h - * @brief - */ - -#ifndef ENCRYPT_H -#define ENCRYPT_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup Advanced-Encryption-Symmetric Advanced API for the symmetric encryption. - * - * TODO: extended description and examples. - * - * TODO: Let's describe how to set additional params (like GCM, CCM) - * - * @{ - */ - -/** - * @brief crypto_encrypt_init Initializes an encryption context. - * - * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). - * @param[in] algo Encryption algorithm that will be used. - * @param[in] bcm Chaining mode that will be used. - * @param[in] sym_key Symmetric key that will be used. - * @param[in] iv Initialization vector that will be used. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_encrypt_init(crypto_ctx_h *ctx, - crypto_enc_algo_e algo, - crypto_block_cipher_mode_e bcm, - const crypto_key_h sym_key, - const crypto_key_h iv); - -/** - * @brief crypto_encrypt_update Encrypts chunk of the data. - * - * @param[in,out] ctx Context created by @see crypto_encrypt_init. - * @param[in] plain Plain text to be encrypted. - * @param[in] plain_len Length of the plain text. - * @param[out] cipher Buffer for the encrypted data (must be allocated by client, @see crypto_get_output_length). - * @param[out] cipher_len Length of the encrypted data, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_encrypt_update(crypto_ctx_h ctx, - const char *plain, - size_t plain_len, - char *cipher, - size_t *cipher_len); - -/** - * @brief crypto_encrypt_final Encrypts the final chunk of the data. - * - * @param[in,out] ctx A valid encrypt context. - * @param[out] cipher Final piece of the encrypted data (must be allocated by client, @see crypto_get_block_length). - * @param[out] cipher_len Length of the final piece, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_encrypt_final(crypto_ctx_h ctx, - char *cipher, - size_t *cipher_len); - -/** - * @brief crypto_decrypt_init Initializes an decryption context. - * - * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). - * @param[in] algo Encryption algorithm that was used to encrypt the data. - * @param[in] bcm Chaining mode that was used to encrypt the data. - * @param[in] sym_key Symmetric key that was used to encrypt the data. - * @param[in] iv Initialization vector that was used to encrypt the data. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_decrypt_init(crypto_ctx_h *ctx, - crypto_enc_algo_e algo, - crypto_block_cipher_mode_e bcm, - const crypto_key_h sym_key, - const crypto_key_h iv); - -/** - * @brief crypto_decrypt_update Decrypts chunk of the data. - * - * @param[in,out] ctx Context created by @see crypto_decrypt_init. - * @param[in] cipher Cipher text to be decrypted. - * @param[in] cipher_len Length of the cipher text. - * @param[out] plain Buffer for the decrypted data (must be allocated by client, @see crypto_get_output_length). - * @param[out] plain_len Length of the decrypted data, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_decrypt_update(crypto_ctx_h ctx, - const char *cipher, - size_t cipher_len, - char *plain, - size_t *plain_len); - -/** - * @brief crypto_decrypt_final Decrypts the final chunk of the data. - * - * @param[in,out] ctx A valid decrypt context. - * @param[out] plain Final piece of the decrypted data (must be allocated by client, @see crypto_get_block_length). - * @param[out] plain_len Length of the final piece, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_decrypt_final(crypto_ctx_h ctx, - char *plain, - size_t *plain_len); - -/**@}*/ - -/** - * @defgroup Advanced-Encryption-Asymmetric Advanced API for the asymmetric encryption. - * - * TODO: extended description and examples. - * - * TODO: Seal does more than just encrypt. It first generates the encryption key and IV, - * then encrypts whole message using this key (and selected symmetric algorithm). - * Finally it encrypts symmetric key with public key. - * - * @{ - */ - -/** - * @brief crypto_seal_init Initializes an asymmetric encryption context. - * - * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). - * @param[in] pub_key Public key of the peer that will receive the encrypted data. - * @param[in] algo Symmetric algorithm that will be used. - * @param[in] bcm Block chaining mode for the symmetric algorithm. - * @param[out] sym_key Generated symmetric key that will be used. It is encrypted with peer's public key. - * @param[out] iv Generated initialization vector that will be used. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_seal_init(crypto_ctx_h *ctx, - const crypto_key_h pub_key, - crypto_enc_algo_e algo, - crypto_block_cipher_mode_e bcm, - crypto_key_h *sym_key, - crypto_key_h *iv); - -/** - * @brief crypto_seal_update Encrypts piece of the data. - * - * @param[in,out] ctx Context created by @see crypto_seal_init. - * @param[in] plain Plain text to be encrypted. - * @param[in] plain_len Length of the plain text. - * @param[out] cipher Buffer for the encrypted data (must be allocated by client, @see crypto_get_output_length). - * @param[out] cipher_len Length of the encrypted data, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_seal_update(crypto_ctx_h ctx, - const char *plain, - size_t plain_len, - char *cipher, - size_t *cipher_len); - -/** - * @brief crypto_seal_final Encrypts the final piece of the data. - * - * @param[in,out] ctx A valid seal context. - * @param[out] cipher Final piece of the encrypted data (must be allocated by client, @see crypto_get_block_length). - * @param[out] cipher_len Length of the final piece, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_seal_final(crypto_ctx_h ctx, - char *cipher, - size_t *cipher_len); - -/** - * @brief crypto_open_init Initializes an asymmetric decryption context. - * - * @param[out] ctx Newly created context. Must be freed by @see crypto_ctx_free. - * @param[in] prv_key Private key, part of the pair that was used for the encryption. - * @param[in] algo Symmetric algorithm that was used for the encryption. - * @param[in] bcm Block chaining mode for the symmetric algorithm. - * @param[in] sym_key Symmetric key, encrypted with the public key, that was used to encrypt the data. - * @param[in] iv Initialization vector that was used for the encryption. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_open_init(crypto_ctx_h *ctx, - const crypto_key_h prv_key, - crypto_enc_algo_e algo, - crypto_block_cipher_mode_e bcm, - const crypto_key_h sym_key, - const crypto_key_h iv); - -/** - * @brief crypto_open_update Decrypts piece of the data. - * - * @param[in,out] ctx Context created by @see crypto_open_init. - * @param[in] cipher Cipher text to be decrypted. - * @param[in] cipher_len Length of the cipher text. - * @param[out] plain Buffer for the decrypted data (must be allocated by client, @see crypto_get_output_length). - * @param[out] plain_len Length of the decrypted data, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_open_update(crypto_ctx_h ctx, - const char *cipher, - size_t cipher_len, - char *plain, - size_t *plain_len); - -/** - * @brief crypto_open_final Decrypts last chunk of sealed message. - * - * @param[in,out] ctx A valid open context. - * @param[out] plain Final piece of the decrypted data (must be allocated by client, @see crypto_get_block_length). - * @param[out] plain_len Length of the final piece, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_open_final(crypto_ctx_h ctx, - char *plain, - size_t *plain_len); - -/**@}*/ -#ifdef __cplusplus -} /* extern */ -#endif - -#endif /* ENCRYPT_H */ diff --git a/src/include/crypto/error.h b/src/include/crypto/error.h deleted file mode 100644 index 55e7900..0000000 --- a/src/include/crypto/error.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file error.h - * @brief - */ - -#ifndef ERROR_H -#define ERROR_H - -/* - TODO: Error enums should be placed here - */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} /* extern */ -#endif - -#endif /* ERROR_H */ diff --git a/src/include/crypto/key.h b/src/include/crypto/key.h deleted file mode 100644 index b81a1f5..0000000 --- a/src/include/crypto/key.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file key.h - * @brief - */ - -#ifndef KEY_H -#define KEY_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup Key Key and IV handling functions - * - * TODO: extended description and examples. - * - * @{ - */ - -#define CRYPTO_KEY_NULL ((crypto_key_h) NULL) - -// TODO: We need a way to import keys encrypted with hw (or other) keys. New function like crypto_key_load or sth?? - -/** - * @brief crypto_key_get_length Get key's length. - * - * @param[in] key Key which length we return. - * - * @return negative on error (@see error.h) or key length. - */ -int crypto_key_get_length(const crypto_key_h *key); - -/** - * @brief crypto_key_import Imports a key from the arbitrary format. - * - * @param[out] key Returned key (must be freed with @see crypto_key_free). - * @param[in] key_fmt Format of the key. - * @param[in] key_type Type of the key. - * @param[in] data Blob containing the key. - * @param[in] data_len Size of the blob. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_key_import(crypto_key_h *key, - crypto_key_fmt_e key_fmt, - crypto_key_type_e key_type, - const char *data, - size_t data_len); - -/** - * @brief crypto_key_export Exports a key to arbitrary format. Export may fail if key is HW-based. - * - * @param[in] key Key to be exported. - * @param[in] key_fmt Format of the key. - * @param[out] data Data, allocated by the library, containing exported key (must be freed with @see crypto_free). - * @param[out] data_len Size of the output data. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_key_export(const crypto_key_h key, - crypto_key_fmt_e key_fmt, - char **data, - size_t *data_len); - -// TODO: still a matter of ordering, should the key in key_gen functions be first or last? - -/** - * @brief crypto_key_gen Generates a secure symmetric key (or an initialization vector). - * - * @param[out] sym_key Newly generated key (must be freed with @see crypto_key_free). - * @param[in] key_type Type of the key to be generated. - * @param[in] key_len Length of the key to be generated. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_key_gen(crypto_key_h *sym_key, - crypto_key_type_e key_type, - size_t key_len); - -/** - * @brief crypto_key_gen_pair Generates a new key pair. - * - * @param[out] prv_key Newly generated private key (must be freed with @see crypto_key_free). - * @param[out] pub_key Newly generated public key (must be freed with @see crypto_key_free). - * @param[in] key_type Type of the key to be generated (must be CRYPTO_KEY_TYPE_PAIR*). - * @param[in] key_len Length of the key to be generated. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_key_gen_pair(crypto_key_h *prv_key, - crypto_key_h *pub_key, - crypto_key_type_e key_type, - size_t key_len); - -/** - * @brief crypto_key_free Frees the key created by the library. - * Passing CRYPTO_KEY_NULL is allowed. - * - * @param key Key to be freed. - * - */ -void crypto_key_free(crypto_key_h key); - -/**@}*/ - -/** - * @defgroup Key-Derivation Key derivation functions - * - * TODO: rethink separate group. - * TODO: extended description and examples. - * - * @{ - */ - -/** - * @brief crypto_key_derive_dh Derives a key using Diffie-Helmann or EC Diffie-Helmann key exchange protocol. - * - * @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 (must be freed with @see crypto_key_free). - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_key_derive_dh(const crypto_key_h prv_key, - const crypto_key_h pub_key, - crypto_key_h *sym_key); - -/** - * @brief crypto_key_derive_kea Derives a key using KEA key exchange protocol. - * - * @param[in] prv_key Our DH private component. - * @param[in] pub_key Peers' DH public component. - * @param[in] prv_key_auth Our private key used to create signature on our - * DH public component sent to peer to verify our identity. - * @param[in] pub_key_auth Peers' public key used for signature verification - * of pub_key from peer (peer authentication). - * @param[out] sym_key Shared secret, that can be used as a symmetric key (must be freed with @see crypto_key_free). - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_key_derive_kea(const crypto_key_h prv_key, - const crypto_key_h pub_key, - const crypto_key_h prv_key_auth, - const crypto_key_h pub_key_auth, - crypto_key_h *sym_key); - -/** - * @brief crypto_key_derive_pbkdf2 Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm). - * - * @param[in] password User password as a NULL-terminated string. - * @param[in] salt Salt, should be non-zero. - * @param[in] salt_len Length of the salt. - * @param[in] iter Number of iterations. (TODO: add enum to proposed number of iterations, pick sane defaults). - * @param[in] algo Digest algorithm that should be used in key generation. (TODO: sane defaults). - * @param[in] key_len Length of a key to be generated. - * @param[out] key Newly generated key (must be freed with @see crypto_key_free). - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_key_derive_pbkdf2(const char *password, - const char *salt, - size_t salt_len, - int iter, - crypto_digest_algo_e algo, - crypto_key_len_e key_len, - crypto_key_h *key); - -// TODO: specify -//int crypto_key_wrap(crypto_key_h key, ??); -//int crypto_key_unwrap(crypto_key_h key, ??); - -/**@}*/ -#ifdef __cplusplus -} /* extern */ -#endif - -#endif /* KEY_H */ diff --git a/src/include/crypto/sign.h b/src/include/crypto/sign.h deleted file mode 100644 index 8276fa8..0000000 --- a/src/include/crypto/sign.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file sign.h - * @brief - */ - -#ifndef SIGN_H -#define SIGN_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup Advanced-Integrity Advanced API for the integrity handling - HMAC, CMAC and digital signature. - * - * TODO: extended description and examples. - * TODO: add documentation how to set padding etc - * - * @{ - */ - -/** - * @brief crypto_sign_init Initializes a signature context. - * - * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). - * @param[in] algo Digest algorithm that will be used. - * @param[in] key Private or symmetric key that will be used (algorithm is deduced based on key type). - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_sign_init(crypto_ctx_h *ctx, - crypto_digest_algo_e algo, - const crypto_key_h key); - -/** - * @brief crypto_sign_update Feeds the data into the digital signature algorithm. - * - * @param[in,out] ctx Context created by @see crypto_sign_init. - * @param[in] data Data to be signed. - * @param[in] data_len Length of the data. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_sign_update(crypto_ctx_h ctx, - const char *data, - size_t data_len); - -/** - * @brief crypto_sign_final Calculates the final signature. - * - * @param[in,out] ctx A valid sign context. - * @param[out] mac Buffer for the MAC or the signature (must be allocated by client, @see crypto_get_sign_length). - * @param[out] mac_len Length of the MAC or the signature, actual number of bytes written will be returned here. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_sign_final(crypto_ctx_h ctx, - char *mac, - size_t *mac_len); - -/** - * @brief crypto_verify_init Initializes a signature verification context. - * - * @param[out] ctx Newly created context (must be freed with @see crypto_ctx_free). - * @param[in] algo Digest algorithm that will be used. - * @param[in] key Private or symmetric key that will be used (algorithm is deduced based on key type). - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_verify_init(crypto_ctx_h *ctx, - crypto_digest_algo_e algo, - const crypto_key_h key); - -/** - * @brief crypto_verify_update Feeds the data into the digital signature verification algorithm. - * - * @param[in,out] ctx Context created by @see crypto_verify_init. - * @param[in] data Data to be verified. - * @param[in] data_len Length of the data. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_verify_update(crypto_ctx_h ctx, - const char *data, - size_t data_len); - -/** - * @brief crypto_verify_final Performs the verification. - * - * @param[in,out] ctx A valid verify context. - * @param[in] mac Input MAC or signature (returned by @see crypto_sign_final). - * @param[in] mac_len Size of the MAC or the signature. - * - * @return 0 on success, negative on error (@see error.h). - * TODO: CRYTPO_ERROR_SIGNATURE_INVALID when verification fails. - */ -int crypto_verify_final(crypto_ctx_h ctx, - const char *mac, - size_t mac_len); - -/**@}*/ -#ifdef __cplusplus -} /* extern */ -#endif - -#endif /* SIGN_H */ diff --git a/src/include/crypto/simple.h b/src/include/crypto/simple.h deleted file mode 100644 index 5d0ca8a..0000000 --- a/src/include/crypto/simple.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file simple.h - * @brief - */ - -#ifndef SIMPLE_H -#define SIMPLE_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup Simple-API Simple API. - * - * 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 chaining is not supported - * - All outputs are allocated by the library - * - * TODO: extended description and examples. - * - * @{ - */ - -/** - * @brief crypto_digest_calc Calculate a digest of a buffer. - * - * @param[in] algo Digest algorithm (select @see CRYPTO_DIGEST_SHA256 if unsure). - * @param[in] data Data from which the digest is to be calculated. - * @param[in] data_len Length of the data. - * @param[out] digest Message digest, will be allocated by the library (should be freed with @see crypto_free). - * @param[out] digest_len Length of message digest (depends on algorithm). - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_digest_calc(crypto_digest_algo_e algo, - const char *data, - size_t data_len, - char **digest, - size_t *digest_len); - -/** - * @brief crypto_encrypt Encrypt data using a symmetric cipher. - * - * @param[in] algo Encryption algorithm (select @see CRYPTO_ENC_AES if unsure). - * @param[in] bcm Chaining mode (select @see CRYPTO_BCM_CBC if unsure). - * @param[in] sym_key Symmetric encryption key (@see key.h for key generation functions). - * @param[in] iv Initialization vector. - * @param[in] plain Plain text to be encrypted. - * @param[in] plain_len Length of the plain text. - * @param[out] cipher Encrypted data, will be allocated by the library (should be freed with @see crypto_free). - * @param[out] cipher_len Length of the encrypted data (may be larger than decrypted). - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_encrypt(crypto_enc_algo_e algo, - crypto_block_cipher_mode_e bcm, - const crypto_key_h sym_key, - const crypto_key_h iv, - const char *plain, - size_t plain_len, - char **cipher, - size_t *cipher_len); - -/** - * @brief crypto_decrypt Decrypta data using a symmetric cipher. - * - * @param[in] algo Decryption algorithm that was used to encrypt the data. - * @param[in] bcm Chaining mode that was used to encrypt the data. - * @param[in] sym_key Symmetric encryption key that was used to encrypt the data. - * @param[in] iv Initialization vector that was used to encrypt the data. - * @param[in] cipher Cipher text to be decrypted. - * @param[in] cipher_len Length of cipher text. - * @param[out] plain Decrypted data, will be allocated by the library (should be freed with @see crypto_free). - * @param[out] plain_len Length of the decrypted data. - * - * @return 0 on success, negative on error (@see error.h). - */ -int crypto_decrypt(crypto_enc_algo_e algo, - crypto_block_cipher_mode_e bcm, - const crypto_key_h sym_key, - const crypto_key_h iv, - const char *cipher, - size_t cipher_len, - char **plain, - size_t * plain_len); - -// TODO: sign/verify - -/**@}*/ -#ifdef __cplusplus -} /* extern */ -#endif - -#endif /* SIMPLE_H */ diff --git a/src/include/crypto/types.h b/src/include/crypto/types.h deleted file mode 100644 index c2b4a23..0000000 --- a/src/include/crypto/types.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Krzysztof Jackiewicz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file types.h - * @brief - */ - -#ifndef TYPES_H -#define TYPES_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup Crypto-Types Enumerations for CryptoAPI - * - * TODO: extended description. - * - * @{ - */ - -/** - * @brief Context - */ -typedef struct __crypto_ctx *crypto_ctx_h; - -/** - * @brief Key - */ -typedef struct __crypto_key_s *crypto_key_h; - -/** - * @brief Key formats - */ -typedef enum { - CRYPTO_KEY_FORMAT_RAW, /**< key is in clear format */ - CRYPTO_KEY_FORMAT_BASE64, /**< key is encoded in ASCII-base64 */ - CRYPTO_KEY_FORMAT_PEM, /**< key is in PEM file format */ - CRYPTO_KEY_FORMAT_DER /**< key is in DER file format */ -} crypto_key_fmt_e; - -/** - * @brief Key types, IV is considered as key - */ -typedef enum { - CRYPTO_KEY_TYPE_SYMMETRIC, /**< Generic symmetric cipher KEY */ - CRYPTO_KEY_TYPE_DES, /**< DES* key - must be handled differently because of parity bits */ - CRYPTO_KEY_TYPE_IV, /**< IV for symmetric algorithms */ - - CRYPTO_KEY_TYPE_RSA_PUB, /**< RSA public key */ - CRYPTO_KEY_TYPE_RSA_PRIV, /**< RSA private key */ - - CRYPTO_KEY_TYPE_DSA_PUB, /**< DSA public key */ - CRYPTO_KEY_TYPE_DSA_PRIV, /**< DSA private key */ - - CRYPTO_KEY_TYPE_DH_PUB, /**< Diffie-Hellman public key */ - CRYPTO_KEY_TYPE_DH_PRIV, /**< Diffie-Hellman private key */ - - CRYPTO_KEY_TYPE_ECC_PUB, /**< ECC public key */ - CRYPTO_KEY_TYPE_ECC_PRIV, /**< ECC private key */ - - CRYPTO_KEY_TYPE_PAIR_RSA, /**< Pair of RSA keys */ - CRYPTO_KEY_TYPE_PAIR_DSA, /**< Pair of DSA keys */ - CRYPTO_KEY_TYPE_PAIR_DH, /**< Pair of Diffie-Hellman keys */ - CRYPTO_KEY_TYPE_PAIR_ECC /**< Pair of ECC keys */ -} crypto_key_type_e; - -/** - * @brief Key length, It is possible to use arbitrary integer instead, this enums are placed here to avoid magic numbers. - */ -typedef enum { - CRYPTO_KEY_IV_UNSAFE_24BIT = 24, /**< 24-bit IV */ - CRYPTO_KEY_IV_64BIT = 64, /**< 64-bit IV */ - CRYPTO_KEY_IV_128BIT = 128, /**< 128-bit IV */ - CRYPTO_KEY_IV_256BIT = 256, /**< 256-bit IV */ - CRYPTO_KEY_CURVE_P192 = 192, /**< ECC: P192 curve */ - CRYPTO_KEY_CURVE_P256 = 256, /**< ECC: P-256 curve */ - CRYPTO_KEY_CURVE_P384 = 384, /**< ECC: SECP-384 curve */ - CRYPTO_KEY_UNSAFE_40BIT = 40, - CRYPTO_KEY_UNSAFE_56BIT = 56, - CRYPTO_KEY_UNSAFE_80BIT = 80, - CRYPTO_KEY_UNSAFE_112BIT = 112, - CRYPTO_KEY_UNSAFE_128BIT = 128, - CRYPTO_KEY_192BIT = 192, - CRYPTO_KEY_256BIT = 256, - CRYPTO_KEY_512BIT = 512, - CRYPTO_KEY_1024BIT = 1024, - CRYPTO_KEY_2048BIT = 2048, - CRYPTO_KEY_3072BIT = 3072, - CRYPTO_KEY_4096BIT = 4096 -} crypto_key_len_e; - -/** - * @brief Message digest algorithms. CMAC is included to simplify API - */ -typedef enum { - CRYPTO_DIGEST_MD5, /**< Message digest algorithm MD5 */ - CRYPTO_DIGEST_SHA1, /**< Message digest algorithm SHA1 */ - CRYPTO_DIGEST_SHA224, /**< Message digest algorithm SHA2, 224bit */ - CRYPTO_DIGEST_SHA256, /**< Message digest algorithm SHA2, 256bit */ - CRYPTO_DIGEST_SHA384, /**< Message digest algorithm SHA2, 384bit */ - CRYPTO_DIGEST_SHA512, /**< Message digest algorithm SHA2, 512bit */ - CRYPTO_DIGEST_CMAC /**< TODO: perhaps CMAC should be handled differently */ -} crypto_digest_algo_e; - -/** - * @brief Symmetric encryption algorithms - */ -typedef enum { - CRYPTO_ENC_AES = 0, /**< AES encryption. - - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) - Supported key lengths: @c 128, @c 192 and @c 256 */ - - CRYPTO_ENC_UNSAFE_DES, /**< DES encryption. - - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) - Supported key lengths: @c 56 */ - - CRYPTO_ENC_UNSAFE_3DES_2TDEA, /**< 3DES 2-key encryption. - - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) - Use double DES keys to perform corresponding 2-key 3DES encryption. Supported key lengths: @c 112 */ - - CRYPTO_ENC_3DES_3TDEA, /**< 3DES 3-key encryption. - - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) - Use triple DES keys to perform corresponding 3-key 3DES encryption. Supported key lengths: @c 168 */ - - CRYPTO_ENC_UNSAFE_RC2, /**< RC2 encryption. - - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) - The key length is extracted from the key buffer. Supported key lengths: 8-1024 bits in steps of 8 bits. */ - - CRYPTO_ENC_UNSAFE_RC4, /**< RC4 encryption. - The key length is extracted from the key buffer. Supported key lengths: 40–2048 bits in steps of 8 bits */ - - CRYPTO_ENC_CAST5, /**< CAST5 encryption. - - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) - The key length is extracted from the key buffer. Supported key lengths: 40-128 bits in steps of 8 bits */ - - CRYPTO_ENC_UNSAFE_SKIPJACK /**< SKIPJACK algorithm - - see #crypto_block_cipher_mode_e for details on additional parameters (mandatory) - Supported key length: 80 bits */ -} crypto_enc_algo_e; - -/** - * @brief Chaining modes for block ciphers - */ -typedef enum { - CRYPTO_BCM_ECB, /**< ECB block cipher mode. Encrypts 64 bit at a time. No IV is used. */ - - CRYPTO_BCM_CTR, /**< CTR block cipher mode. 16-byte initialization vector is mandatory. - Supported parameters: - - CRYPTO_PARAM_CTR_CNT = length of counter block in bits - (optional, only 128b is supported at the moment) */ - - CRYPTO_BCM_CBC, /**< CBC block cipher mode. 16-byte initialization vector is mandatory. */ - - CRYPTO_BCM_GCM, /**< GCM block cipher mode. IV is needed. - Supported parameters: - - CRYPTO_PARAM_TAG = GCM tag - - CRYPTO_PARAM_AAD = additional authentication data(optional) */ - - CRYPTO_BCM_CFB, /**< CFB block cipher mode. 16-byte initialization vector is mandatory. */ - - CRYPTO_BCM_OFB, /**< OFB block cipher mode. 16-byte initialization vector is mandatory. */ - - CRYPTO_BCM_OCB, /**< Offest Codebook Mode (AES) */ - - CRYPTO_BCM_CCM /**< CBC-MAC Mode (AES) */ - -} crypto_block_cipher_mode_e; - - -/** - * @brief Non-standard parameters for algorithms - */ -typedef enum { - CRYPTO_PARAM_PADDING, /**< Padding */ - - CRYPTO_PARAM_CTR_CNT, /**< CTR Counter bits */ - - CRYPTO_PARAM_GCM_AAD, /**< GCM Additional Authentication Data */ - CRYPTO_PARAM_GCM_TAG, /**< GCM Tag bits */ - CRYPTO_PARAM_GCM_TAG_LEN, /**< GCM Tag length */ - - CRYPTO_PARAM_CCM_AAD, /**< CCM Additional Authentication Data */ - CRYPTO_PARAM_CCM_TAG, /**< CCM Tag bits */ - CRYPTO_PARAM_CCM_TAG_LEN, /**< CCM Tag length */ -} crypto_ex_param_e; - -/** - * @brief Paddings supported by CryptoAPI - */ -typedef enum { - CRYPTO_PADDING_NONE = 0, /**< total number of data MUST multiple of block size, Default */ - CRYPTO_PADDING_ZEROS, /**< pad with zeros */ - CRYPTO_PADDING_ISO10126, /**< ISO 10126 */ - CRYPTO_PADDING_ANSIX923, /**< ANSI X.923 padding*/ - CRYPTO_PADDING_ANSIX931, /**< ANSI X.931 padding*/ - CRYPTO_PADDING_PKCS1, /**< RSA signature creation */ - CRYPTO_PADDING_PKCS7 /**< Byte padding for symetric algos (RFC 5652), (PKCS5 padding is the same) */ -} crypto_padding_e; - -/**@}*/ -#ifdef __cplusplus -} /* extern */ -#endif - -#endif /* TYPES_H */ diff --git a/src/key.c b/src/key.c new file mode 100644 index 0000000..d50c95a --- /dev/null +++ b/src/key.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +#include +#include +#include +#include + +#include +#include + +#include "key_p.h" + +// Sanity check on key +inline void key_sanity_check(const crypto_key_h key) +{ + assert(key->length); + assert(key->length % 8 == 0); +} + +int crypto_key_get_length(const crypto_key_h key) +{ + if (!key) + return CRYPTO_ERROR_INVALID_ARGUMENT; + key_sanity_check(key); + + return key->length; +} + +int crypto_key_import(crypto_key_h *key, + crypto_key_fmt_e key_fmt, + crypto_key_type_e key_type, + const char *data, + size_t data_len) +{ + crypto_key_h nk = NULL; + + if (!key || !data || !data_len) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + if (key_type != CRYPTO_KEY_TYPE_SYMMETRIC) + return CRYPTO_ERROR_NOT_IMPLEMENTED; + + if (key_fmt != CRYPTO_KEY_FORMAT_RAW) + return CRYPTO_ERROR_NOT_IMPLEMENTED; + + if (sizeof(struct __crypto_key_s) + data_len < data_len) + return CRYPTO_ERROR_TOO_BIG_ARGUMENT; + + nk = crypto_alloc(sizeof(struct __crypto_key_s) + data_len); + if (!nk) + return CRYPTO_ERROR_OUT_OF_MEMORY; + + memcpy(nk->d, data, data_len); + nk->length = data_len * 8; + nk->type = key_type; + *key = nk; + + return 0; +} + +int crypto_key_export(const crypto_key_h key, + crypto_key_fmt_e key_fmt, + char **data, + size_t *data_len) +{ + int byte_len; + + if (!key || !data || !data_len) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + if (key->type != CRYPTO_KEY_TYPE_SYMMETRIC) + return CRYPTO_ERROR_NOT_IMPLEMENTED; + + if (key_fmt != CRYPTO_KEY_FORMAT_RAW) + return CRYPTO_ERROR_NOT_IMPLEMENTED; + + key_sanity_check(key); + + byte_len = key->length / 8; + *data = crypto_alloc(byte_len); + memcpy(*data, key->d, byte_len); + *data_len = byte_len; + + return 0; +} + +int crypto_key_gen(crypto_key_h *sym_key, + crypto_key_type_e key_type, + size_t key_len) +{ + if (!sym_key || key_type != CRYPTO_KEY_TYPE_SYMMETRIC) + return -1; + + *sym_key = crypto_alloc(sizeof(struct __crypto_key_s) + key_len); + if (!*sym_key) + return -1; + + (*sym_key)->length = key_len; + (*sym_key)->type = key_type; + return crypto_rand_bytes((*sym_key)->d, key_len); +} + +int crypto_key_gen_pair(crypto_key_h *prv_key, + crypto_key_h *pub_key, + crypto_key_type_e key_type, + size_t key_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +void crypto_key_free(crypto_key_h key) +{ + if (!key) + return; + + crypto_free(key); +} + +int crypto_key_derive_dh(const crypto_key_h prv_key, + const crypto_key_h pub_key, + crypto_key_h *sym_key) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_key_derive_kea(const crypto_key_h prv_key, + const crypto_key_h pub_key, + const crypto_key_h prv_key_auth, + const crypto_key_h pub_key_auth, + crypto_key_h *sym_key) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_key_derive_pbkdf2(const char *password, + const char *salt, + size_t salt_len, + int iter, + crypto_digest_algo_e algo, + crypto_key_len_e key_len, + crypto_key_h *key) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} diff --git a/src/key_p.h b/src/key_p.h new file mode 100644 index 0000000..54598e1 --- /dev/null +++ b/src/key_p.h @@ -0,0 +1,36 @@ +/* + * 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 + */ + +#ifndef KEY_P_H +#define KEY_P_H +#include +#include + +/** + * @file key_p.h + * @brief Private header for key.c + */ + +struct __crypto_key_s { + crypto_key_type_e type; + size_t length; + char d[0]; +}; + +#endif + diff --git a/src/sign.c b/src/sign.c new file mode 100644 index 0000000..954252d --- /dev/null +++ b/src/sign.c @@ -0,0 +1,67 @@ +/* + * 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 + +int crypto_sign_init(crypto_ctx_h *ctx, + crypto_digest_algo_e algo, + const crypto_key_h key) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_sign_update(crypto_ctx_h ctx, + const char *data, + size_t data_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_sign_final(crypto_ctx_h ctx, + char *mac, + size_t *mac_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_verify_init(crypto_ctx_h *ctx, + crypto_digest_algo_e algo, + const crypto_key_h key) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_verify_update(crypto_ctx_h ctx, + const char *data, + size_t data_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} + +int crypto_verify_final(crypto_ctx_h ctx, + const char *mac, + size_t mac_len) +{ + return CRYPTO_ERROR_NOT_IMPLEMENTED; +} diff --git a/src/simple.c b/src/simple.c new file mode 100644 index 0000000..7f5cbc1 --- /dev/null +++ b/src/simple.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Jackiewicz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +int crypto_digest_calc(crypto_digest_algo_e algo, + const char *data, + size_t data_len, + char **digest, + size_t *digest_len) +{ + crypto_ctx_h ctx; + int ret; + char *ldigest; + size_t ldigest_len; + + if (!data || !data_len || !digest || !digest_len) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + ret = crypto_digest_init(&ctx, algo); + if (ret < 0) + return ret; + + ret = crypto_digest_update(ctx, data, data_len); + if (ret < 0) + goto err; + + ret = crypto_get_digest_length(ctx); + if (ret < 0) + goto err; + + ldigest_len = ret; + ldigest = crypto_alloc(ldigest_len); + if (!ldigest) + goto err; + + ret = crypto_digest_final(ctx, ldigest, &ldigest_len); + if (ret < 0) + goto err_free; + + crypto_ctx_free(ctx); + + *digest_len = ldigest_len; + *digest = ldigest; + return 0; + +err_free: + crypto_free(ldigest); +err: + crypto_ctx_free(ctx); + return ret; +} + +int crypto_encrypt(crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv, + const char *plain, + size_t plain_len, + char **cipher, + size_t *cipher_len) +{ + crypto_ctx_h ctx; + int ret; + char *lcipher; + size_t out_len, lcipher_len, written; + + if (!plain || !plain_len || !cipher || !cipher_len | !sym_key | !iv) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + if (plain_len > INT_MAX) /* TODO: this is because get_output_length returns signed int - perhaps we should change that */ + return CRYPTO_ERROR_TOO_BIG_ARGUMENT; + + ret = crypto_encrypt_init(&ctx, algo, bcm, sym_key, iv); + if (ret < 0) + return ret; + + ret = crypto_get_output_length(ctx, plain_len); + if (ret < 0) + goto err; + + lcipher_len = ret; + lcipher = crypto_alloc(lcipher_len); + if (!lcipher) + goto err; + + out_len = lcipher_len; + ret = crypto_encrypt_update(ctx, plain, plain_len, lcipher, &out_len); + if (ret < 0) + goto err_free; + + assert (out_len <= lcipher_len); + + written = out_len; + out_len = lcipher_len - written; + ret = crypto_encrypt_final(ctx, lcipher + written, &out_len); + if (ret < 0) + goto err_free; + + assert (out_len + written == lcipher_len); + + crypto_ctx_free(ctx); + + *cipher = lcipher; + *cipher_len = lcipher_len; + return 0; + +err_free: + crypto_free(lcipher); +err: + crypto_ctx_free(ctx); + return ret; +} + +int crypto_decrypt(crypto_enc_algo_e algo, + crypto_block_cipher_mode_e bcm, + const crypto_key_h sym_key, + const crypto_key_h iv, + const char *cipher, + size_t cipher_len, + char **plain, + size_t *plain_len) +{ + crypto_ctx_h ctx; + int ret; + char *lplain; + size_t out_len, lplain_len, written; + + if (!cipher || !cipher_len || !plain || !plain_len || !sym_key || !iv) + return CRYPTO_ERROR_INVALID_ARGUMENT; + + if (cipher_len > INT_MAX) /* TODO: this is because get_output_length returns signed int - perhaps we should change that */ + return CRYPTO_ERROR_TOO_BIG_ARGUMENT; + + ret = crypto_decrypt_init(&ctx, algo, bcm, sym_key, iv); + if (ret < 0) + return ret; + + ret = crypto_get_output_length(ctx, cipher_len); + if (ret < 0) + goto err; + + lplain_len = ret; + lplain = crypto_alloc(lplain_len); + if (!lplain) + goto err; + + out_len = lplain_len; + ret = crypto_decrypt_update(ctx, cipher, cipher_len, lplain, &out_len); + if (ret < 0) + goto err_free; + + assert (out_len <= lplain_len); + + written = out_len; + out_len = lplain_len - written; + ret = crypto_decrypt_final(ctx, lplain + written, &out_len); + if (ret < 0) + goto err_free; + + assert (out_len + written == lplain_len); + + crypto_ctx_free(ctx); + + *plain = lplain; + *plain_len = lplain_len; + return 0; + +err_free: + crypto_free(lplain); +err: + crypto_ctx_free(ctx); + return ret; +}