diff --git a/winpr/include/winpr/custom-crypto.h b/winpr/include/winpr/custom-crypto.h index 32ff5d4c2..cc1c37332 100644 --- a/winpr/include/winpr/custom-crypto.h +++ b/winpr/include/winpr/custom-crypto.h @@ -174,59 +174,68 @@ extern "C" #define WINPR_AES_BLOCK_SIZE 16 /* cipher operation types */ -#define WINPR_ENCRYPT 0 -#define WINPR_DECRYPT 1 +#define WINPR_CIPHER_MAX_IV_LENGTH 16u +#define WINPR_CIPHER_MAX_KEY_LENGTH 64u + +typedef enum +{ + WINPR_ENCRYPT = 0, + WINPR_DECRYPT = 1 +} WINPR_CRYPTO_OPERATION; /* cipher types */ -#define WINPR_CIPHER_NONE 0 -#define WINPR_CIPHER_NULL 1 -#define WINPR_CIPHER_AES_128_ECB 2 -#define WINPR_CIPHER_AES_192_ECB 3 -#define WINPR_CIPHER_AES_256_ECB 4 -#define WINPR_CIPHER_AES_128_CBC 5 -#define WINPR_CIPHER_AES_192_CBC 6 -#define WINPR_CIPHER_AES_256_CBC 7 -#define WINPR_CIPHER_AES_128_CFB128 8 -#define WINPR_CIPHER_AES_192_CFB128 9 -#define WINPR_CIPHER_AES_256_CFB128 10 -#define WINPR_CIPHER_AES_128_CTR 11 -#define WINPR_CIPHER_AES_192_CTR 12 -#define WINPR_CIPHER_AES_256_CTR 13 -#define WINPR_CIPHER_AES_128_GCM 14 -#define WINPR_CIPHER_AES_192_GCM 15 -#define WINPR_CIPHER_AES_256_GCM 16 -#define WINPR_CIPHER_CAMELLIA_128_ECB 17 -#define WINPR_CIPHER_CAMELLIA_192_ECB 18 -#define WINPR_CIPHER_CAMELLIA_256_ECB 19 -#define WINPR_CIPHER_CAMELLIA_128_CBC 20 -#define WINPR_CIPHER_CAMELLIA_192_CBC 21 -#define WINPR_CIPHER_CAMELLIA_256_CBC 22 -#define WINPR_CIPHER_CAMELLIA_128_CFB128 23 -#define WINPR_CIPHER_CAMELLIA_192_CFB128 24 -#define WINPR_CIPHER_CAMELLIA_256_CFB128 25 -#define WINPR_CIPHER_CAMELLIA_128_CTR 26 -#define WINPR_CIPHER_CAMELLIA_192_CTR 27 -#define WINPR_CIPHER_CAMELLIA_256_CTR 28 -#define WINPR_CIPHER_CAMELLIA_128_GCM 29 -#define WINPR_CIPHER_CAMELLIA_192_GCM 30 -#define WINPR_CIPHER_CAMELLIA_256_GCM 31 -#define WINPR_CIPHER_DES_ECB 32 -#define WINPR_CIPHER_DES_CBC 33 -#define WINPR_CIPHER_DES_EDE_ECB 34 -#define WINPR_CIPHER_DES_EDE_CBC 35 -#define WINPR_CIPHER_DES_EDE3_ECB 36 -#define WINPR_CIPHER_DES_EDE3_CBC 37 -#define WINPR_CIPHER_BLOWFISH_ECB 38 -#define WINPR_CIPHER_BLOWFISH_CBC 39 -#define WINPR_CIPHER_BLOWFISH_CFB64 40 -#define WINPR_CIPHER_BLOWFISH_CTR 41 -#define WINPR_CIPHER_ARC4_128 42 -#define WINPR_CIPHER_AES_128_CCM 43 -#define WINPR_CIPHER_AES_192_CCM 44 -#define WINPR_CIPHER_AES_256_CCM 45 -#define WINPR_CIPHER_CAMELLIA_128_CCM 46 -#define WINPR_CIPHER_CAMELLIA_192_CCM 47 -#define WINPR_CIPHER_CAMELLIA_256_CCM 48 +typedef enum +{ + WINPR_CIPHER_NONE = 0, + WINPR_CIPHER_NULL = 1, + WINPR_CIPHER_AES_128_ECB = 2, + WINPR_CIPHER_AES_192_ECB = 3, + WINPR_CIPHER_AES_256_ECB = 4, + WINPR_CIPHER_AES_128_CBC = 5, + WINPR_CIPHER_AES_192_CBC = 6, + WINPR_CIPHER_AES_256_CBC = 7, + WINPR_CIPHER_AES_128_CFB128 = 8, + WINPR_CIPHER_AES_192_CFB128 = 9, + WINPR_CIPHER_AES_256_CFB128 = 10, + WINPR_CIPHER_AES_128_CTR = 11, + WINPR_CIPHER_AES_192_CTR = 12, + WINPR_CIPHER_AES_256_CTR = 13, + WINPR_CIPHER_AES_128_GCM = 14, + WINPR_CIPHER_AES_192_GCM = 15, + WINPR_CIPHER_AES_256_GCM = 16, + WINPR_CIPHER_CAMELLIA_128_ECB = 17, + WINPR_CIPHER_CAMELLIA_192_ECB = 18, + WINPR_CIPHER_CAMELLIA_256_ECB = 19, + WINPR_CIPHER_CAMELLIA_128_CBC = 20, + WINPR_CIPHER_CAMELLIA_192_CBC = 21, + WINPR_CIPHER_CAMELLIA_256_CBC = 22, + WINPR_CIPHER_CAMELLIA_128_CFB128 = 23, + WINPR_CIPHER_CAMELLIA_192_CFB128 = 24, + WINPR_CIPHER_CAMELLIA_256_CFB128 = 25, + WINPR_CIPHER_CAMELLIA_128_CTR = 26, + WINPR_CIPHER_CAMELLIA_192_CTR = 27, + WINPR_CIPHER_CAMELLIA_256_CTR = 28, + WINPR_CIPHER_CAMELLIA_128_GCM = 29, + WINPR_CIPHER_CAMELLIA_192_GCM = 30, + WINPR_CIPHER_CAMELLIA_256_GCM = 31, + WINPR_CIPHER_DES_ECB = 32, + WINPR_CIPHER_DES_CBC = 33, + WINPR_CIPHER_DES_EDE_ECB = 34, + WINPR_CIPHER_DES_EDE_CBC = 35, + WINPR_CIPHER_DES_EDE3_ECB = 36, + WINPR_CIPHER_DES_EDE3_CBC = 37, + WINPR_CIPHER_BLOWFISH_ECB = 38, + WINPR_CIPHER_BLOWFISH_CBC = 39, + WINPR_CIPHER_BLOWFISH_CFB64 = 40, + WINPR_CIPHER_BLOWFISH_CTR = 41, + WINPR_CIPHER_ARC4_128 = 42, + WINPR_CIPHER_AES_128_CCM = 43, + WINPR_CIPHER_AES_192_CCM = 44, + WINPR_CIPHER_AES_256_CCM = 45, + WINPR_CIPHER_CAMELLIA_128_CCM = 46, + WINPR_CIPHER_CAMELLIA_192_CCM = 47, + WINPR_CIPHER_CAMELLIA_256_CCM = 48, +} WINPR_CIPHER_TYPE; typedef struct winpr_cipher_ctx_private_st WINPR_CIPHER_CTX; @@ -235,10 +244,29 @@ extern "C" { #endif + /** @brief convert a cipher string to an enum value + * + * @param name the name of the cipher + * @return the \b WINPR_CIPHER_* value matching or \b WINPR_CIPHER_NONE if not found. + * + * @since version 3.10.0 + */ + WINPR_API WINPR_CIPHER_TYPE winpr_cipher_type_from_string(const char* name); + + /** @brief convert a cipher enum value to string + * + * @param md the cipher enum value + * @return the string representation of the value + * + * @since version 3.10.0 + */ + WINPR_API const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE md); + WINPR_API void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx); WINPR_ATTR_MALLOC(winpr_Cipher_Free, 1) - WINPR_API WINPR_CIPHER_CTX* winpr_Cipher_New(int cipher, int op, const void* key, + WINPR_API WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, + WINPR_CRYPTO_OPERATION op, const void* key, const void* iv); WINPR_API BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled); WINPR_API BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, diff --git a/winpr/libwinpr/crypto/cipher.c b/winpr/libwinpr/crypto/cipher.c index d1e2fd298..ee3df9c30 100644 --- a/winpr/libwinpr/crypto/cipher.c +++ b/winpr/libwinpr/crypto/cipher.c @@ -172,8 +172,100 @@ extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md); extern mbedtls_md_type_t winpr_mbedtls_get_md_type(int md); #endif +struct cipher_map +{ + WINPR_CIPHER_TYPE md; + const char* name; +}; +static const struct cipher_map s_cipher_map[] = { + { WINPR_CIPHER_NONE, "none" }, + { WINPR_CIPHER_NULL, "null" }, + { WINPR_CIPHER_AES_128_ECB, "aes-128-ecb" }, + { WINPR_CIPHER_AES_192_ECB, "aes-192-ecb" }, + { WINPR_CIPHER_AES_256_ECB, "aes-256-ecb" }, + { WINPR_CIPHER_AES_128_CBC, "aes-128-cbc" }, + { WINPR_CIPHER_AES_192_CBC, "aes-192-cbc" }, + { WINPR_CIPHER_AES_256_CBC, "aes-256-cbc" }, + { WINPR_CIPHER_AES_128_CFB128, "aes-128-cfb128" }, + { WINPR_CIPHER_AES_192_CFB128, "aes-192-cfb128" }, + { WINPR_CIPHER_AES_256_CFB128, "aes-256-cfb128" }, + { WINPR_CIPHER_AES_128_CTR, "aes-128-ctr" }, + { WINPR_CIPHER_AES_192_CTR, "aes-192-ctr" }, + { WINPR_CIPHER_AES_256_CTR, "aes-256-ctr" }, + { WINPR_CIPHER_AES_128_GCM, "aes-128-gcm" }, + { WINPR_CIPHER_AES_192_GCM, "aes-192-gcm" }, + { WINPR_CIPHER_AES_256_GCM, "aes-256-gcm" }, + { WINPR_CIPHER_CAMELLIA_128_ECB, "camellia-128-ecb" }, + { WINPR_CIPHER_CAMELLIA_192_ECB, "camellia-192-ecb" }, + { WINPR_CIPHER_CAMELLIA_256_ECB, "camellia-256-ecb" }, + { WINPR_CIPHER_CAMELLIA_128_CBC, "camellia-128-cbc" }, + { WINPR_CIPHER_CAMELLIA_192_CBC, "camellia-192-cbc" }, + { WINPR_CIPHER_CAMELLIA_256_CBC, "camellia-256-cbc" }, + { WINPR_CIPHER_CAMELLIA_128_CFB128, "camellia-128-cfb128" }, + { WINPR_CIPHER_CAMELLIA_192_CFB128, "camellia-192-cfb128" }, + { WINPR_CIPHER_CAMELLIA_256_CFB128, "camellia-256-cfb128" }, + { WINPR_CIPHER_CAMELLIA_128_CTR, "camellia-128-ctr" }, + { WINPR_CIPHER_CAMELLIA_192_CTR, "camellia-192-ctr" }, + { WINPR_CIPHER_CAMELLIA_256_CTR, "camellia-256-ctr" }, + { WINPR_CIPHER_CAMELLIA_128_GCM, "camellia-128-gcm" }, + { WINPR_CIPHER_CAMELLIA_192_GCM, "camellia-192-gcm" }, + { WINPR_CIPHER_CAMELLIA_256_GCM, "camellia-256-gcm" }, + { WINPR_CIPHER_DES_ECB, "des-ecb" }, + { WINPR_CIPHER_DES_CBC, "des-cbc" }, + { WINPR_CIPHER_DES_EDE_ECB, "des-ede-ecb" }, + { WINPR_CIPHER_DES_EDE_CBC, "des-ede-cbc" }, + { WINPR_CIPHER_DES_EDE3_ECB, "des-ede3-ecb" }, + { WINPR_CIPHER_DES_EDE3_CBC, "des-ede3-cbc" }, + { WINPR_CIPHER_BLOWFISH_ECB, "blowfish-ecb" }, + { WINPR_CIPHER_BLOWFISH_CBC, "blowfish-cbc" }, + { WINPR_CIPHER_BLOWFISH_CFB64, "blowfish-cfb64" }, + { WINPR_CIPHER_BLOWFISH_CTR, "blowfish-ctr" }, + { WINPR_CIPHER_ARC4_128, "rc4" }, + { WINPR_CIPHER_AES_128_CCM, "aes-128-ccm" }, + { WINPR_CIPHER_AES_192_CCM, "aes-192-ccm" }, + { WINPR_CIPHER_AES_256_CCM, "aes-256-ccm" }, + { WINPR_CIPHER_CAMELLIA_128_CCM, "camellia-128-ccm" }, + { WINPR_CIPHER_CAMELLIA_192_CCM, "camellia-192-ccm" }, + { WINPR_CIPHER_CAMELLIA_256_CCM, "camellia-256-ccm" }, +}; + +static int cipher_compare(const void* a, const void* b) +{ + const WINPR_CIPHER_TYPE* cipher = a; + const struct cipher_map* map = b; + if (*cipher == map->md) + return 0; + return *cipher > map->md ? 1 : -1; +} + +const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE cipher) +{ + WINPR_CIPHER_TYPE lc = cipher; + const struct cipher_map* ret = bsearch(&lc, s_cipher_map, ARRAYSIZE(s_cipher_map), + sizeof(struct cipher_map), cipher_compare); + if (!ret) + return "unknown"; + return ret->name; +} + +static int cipher_string_compare(const void* a, const void* b) +{ + const char* cipher = a; + const struct cipher_map* map = b; + return strcmp(cipher, map->name); +} + +WINPR_CIPHER_TYPE winpr_cipher_type_from_string(const char* name) +{ + const struct cipher_map* ret = bsearch(name, s_cipher_map, ARRAYSIZE(s_cipher_map), + sizeof(struct cipher_map), cipher_string_compare); + if (!ret) + return WINPR_CIPHER_NONE; + return ret->md; +} + #if defined(WITH_OPENSSL) -static const EVP_CIPHER* winpr_openssl_get_evp_cipher(int cipher) +static const EVP_CIPHER* winpr_openssl_get_evp_cipher(WINPR_CIPHER_TYPE cipher) { const EVP_CIPHER* evp = NULL; @@ -320,11 +412,11 @@ static const EVP_CIPHER* winpr_openssl_get_evp_cipher(int cipher) break; case WINPR_CIPHER_CAMELLIA_192_CCM: - evp = EVP_get_cipherbyname("camellia-192-gcm"); + evp = EVP_get_cipherbyname("camellia-192-ccm"); break; case WINPR_CIPHER_CAMELLIA_256_CCM: - evp = EVP_get_cipherbyname("camellia-256-gcm"); + evp = EVP_get_cipherbyname("camellia-256-ccm"); break; case WINPR_CIPHER_DES_ECB: @@ -467,7 +559,8 @@ mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher) } #endif -WINPR_CIPHER_CTX* winpr_Cipher_New(int cipher, int op, const void* key, const void* iv) +WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op, + const void* key, const void* iv) { WINPR_CIPHER_CTX* ctx = NULL; #if defined(WITH_OPENSSL)