mirror of
				https://github.com/libssh2/libssh2.git
				synced 2025-10-30 12:05:34 +03:00 
			
		
		
		
	wincng: add AES CTR mode support (aes128-ctr, aes192-ctr, aes256-ctr)
This commit is contained in:
		
							
								
								
									
										77
									
								
								src/wincng.c
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								src/wincng.c
									
									
									
									
									
								
							| @@ -59,6 +59,7 @@ | ||||
| #include <windows.h> | ||||
| #include <bcrypt.h> | ||||
| #include <math.h> | ||||
| #include "misc.h" | ||||
|  | ||||
| #ifdef HAVE_STDLIB_H | ||||
| #include <stdlib.h> | ||||
| @@ -253,6 +254,17 @@ _libssh2_wincng_init(void) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_ECB, | ||||
|                                       BCRYPT_AES_ALGORITHM, NULL, 0); | ||||
|     if (BCRYPT_SUCCESS(ret)) { | ||||
|         ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_ECB, BCRYPT_CHAINING_MODE, | ||||
|                                 (PBYTE)BCRYPT_CHAIN_MODE_ECB, | ||||
|                                 sizeof(BCRYPT_CHAIN_MODE_ECB), 0); | ||||
|         if (!BCRYPT_SUCCESS(ret)) { | ||||
|             (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_ECB, 0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, | ||||
|                                       BCRYPT_RC4_ALGORITHM, NULL, 0); | ||||
|     if (BCRYPT_SUCCESS(ret)) { | ||||
| @@ -1653,8 +1665,8 @@ _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, | ||||
| { | ||||
|     BCRYPT_KEY_HANDLE hKey; | ||||
|     BCRYPT_KEY_DATA_BLOB_HEADER *header; | ||||
|     unsigned char *pbKeyObject, *pbIV, *key; | ||||
|     unsigned long dwKeyObject, dwIV, dwBlockLength, cbData, keylen; | ||||
|     unsigned char *pbKeyObject, *pbIV, *key, *pbCtr, *pbIVCopy; | ||||
|     unsigned long dwKeyObject, dwIV, dwCtrLength, dwBlockLength, cbData, keylen; | ||||
|     int ret; | ||||
|  | ||||
|     (void)encrypt; | ||||
| @@ -1707,31 +1719,41 @@ _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     if (type.dwUseIV) { | ||||
|         pbIV = malloc(dwBlockLength); | ||||
|         if (!pbIV) { | ||||
|     pbIV = NULL; | ||||
|     pbCtr = NULL; | ||||
|     dwIV = 0; | ||||
|     dwCtrLength = 0; | ||||
|  | ||||
|     if (type.useIV || type.ctrMode) { | ||||
|         pbIVCopy = malloc(dwBlockLength); | ||||
|         if (!pbIVCopy) { | ||||
|             BCryptDestroyKey(hKey); | ||||
|             _libssh2_wincng_safe_free(pbKeyObject, dwKeyObject); | ||||
|             return -1; | ||||
|         } | ||||
|         dwIV = dwBlockLength; | ||||
|         memcpy(pbIV, iv, dwIV); | ||||
|     } else { | ||||
|         pbIV = NULL; | ||||
|         dwIV = 0; | ||||
|     } | ||||
|         memcpy(pbIVCopy, iv, dwBlockLength); | ||||
|  | ||||
|         if (type.ctrMode) { | ||||
|             pbCtr = pbIVCopy; | ||||
|             dwCtrLength = dwBlockLength; | ||||
|         } | ||||
|         else if (type.useIV) { | ||||
|             pbIV = pbIVCopy; | ||||
|             dwIV = dwBlockLength; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ctx->hKey = hKey; | ||||
|     ctx->pbKeyObject = pbKeyObject; | ||||
|     ctx->pbIV = pbIV; | ||||
|     ctx->pbCtr = pbCtr; | ||||
|     ctx->dwKeyObject = dwKeyObject; | ||||
|     ctx->dwIV = dwIV; | ||||
|     ctx->dwBlockLength = dwBlockLength; | ||||
|     ctx->dwCtrLength = dwCtrLength; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, | ||||
|                              _libssh2_cipher_type(type), | ||||
| @@ -1739,7 +1761,7 @@ _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, | ||||
|                              unsigned char *block, | ||||
|                              size_t blocklen) | ||||
| { | ||||
|     unsigned char *pbOutput; | ||||
|     unsigned char *pbOutput, *pbInput; | ||||
|     unsigned long cbOutput, cbInput; | ||||
|     int ret; | ||||
|  | ||||
| @@ -1747,27 +1769,38 @@ _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, | ||||
|  | ||||
|     cbInput = (unsigned long)blocklen; | ||||
|  | ||||
|     if (encrypt) { | ||||
|         ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, | ||||
|     if (type.ctrMode) { | ||||
|         pbInput = ctx->pbCtr; | ||||
|     } else { | ||||
|         pbInput = block; | ||||
|     } | ||||
|  | ||||
|     if (encrypt || type.ctrMode) { | ||||
|         ret = BCryptEncrypt(ctx->hKey, pbInput, cbInput, NULL, | ||||
|                             ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); | ||||
|     } else { | ||||
|         ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, | ||||
|         ret = BCryptDecrypt(ctx->hKey, pbInput, cbInput, NULL, | ||||
|                             ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); | ||||
|     } | ||||
|     if (BCRYPT_SUCCESS(ret)) { | ||||
|         pbOutput = malloc(cbOutput); | ||||
|         if (pbOutput) { | ||||
|             if (encrypt) { | ||||
|                 ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, | ||||
|             if (encrypt || type.ctrMode) { | ||||
|                 ret = BCryptEncrypt(ctx->hKey, pbInput, cbInput, NULL, | ||||
|                                     ctx->pbIV, ctx->dwIV, | ||||
|                                     pbOutput, cbOutput, &cbOutput, 0); | ||||
|             } else { | ||||
|                 ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, | ||||
|                 ret = BCryptDecrypt(ctx->hKey, pbInput, cbInput, NULL, | ||||
|                                     ctx->pbIV, ctx->dwIV, | ||||
|                                     pbOutput, cbOutput, &cbOutput, 0); | ||||
|             } | ||||
|             if (BCRYPT_SUCCESS(ret)) { | ||||
|                 memcpy(block, pbOutput, cbOutput); | ||||
|                 if (type.ctrMode) { | ||||
|                     _libssh2_xor_data(block, block, pbOutput, blocklen); | ||||
|                     _libssh2_aes_ctr_increment(ctx->pbCtr, ctx->dwCtrLength); | ||||
|                 } else { | ||||
|                     memcpy(block, pbOutput, cbOutput); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             _libssh2_wincng_safe_free(pbOutput, cbOutput); | ||||
| @@ -1791,6 +1824,10 @@ _libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx) | ||||
|     _libssh2_wincng_safe_free(ctx->pbIV, ctx->dwBlockLength); | ||||
|     ctx->pbIV = NULL; | ||||
|     ctx->dwBlockLength = 0; | ||||
|  | ||||
|     _libssh2_wincng_safe_free(ctx->pbCtr, ctx->dwCtrLength); | ||||
|     ctx->pbCtr = NULL; | ||||
|     ctx->dwCtrLength = 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										26
									
								
								src/wincng.h
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/wincng.h
									
									
									
									
									
								
							| @@ -55,7 +55,7 @@ | ||||
| #define LIBSSH2_HMAC_SHA512 1 | ||||
|  | ||||
| #define LIBSSH2_AES 1 | ||||
| #define LIBSSH2_AES_CTR 0 | ||||
| #define LIBSSH2_AES_CTR 1 | ||||
| #define LIBSSH2_BLOWFISH 0 | ||||
| #define LIBSSH2_RC4 1 | ||||
| #define LIBSSH2_CAST 0 | ||||
| @@ -88,6 +88,7 @@ struct _libssh2_wincng_ctx { | ||||
|     BCRYPT_ALG_HANDLE hAlgRSA; | ||||
|     BCRYPT_ALG_HANDLE hAlgDSA; | ||||
|     BCRYPT_ALG_HANDLE hAlgAES_CBC; | ||||
|     BCRYPT_ALG_HANDLE hAlgAES_ECB; | ||||
|     BCRYPT_ALG_HANDLE hAlgRC4_NA; | ||||
|     BCRYPT_ALG_HANDLE hAlg3DES_CBC; | ||||
| }; | ||||
| @@ -285,9 +286,11 @@ struct _libssh2_wincng_cipher_ctx { | ||||
|     BCRYPT_KEY_HANDLE hKey; | ||||
|     unsigned char *pbKeyObject; | ||||
|     unsigned char *pbIV; | ||||
|     unsigned char *pbCtr; | ||||
|     unsigned long dwKeyObject; | ||||
|     unsigned long dwIV; | ||||
|     unsigned long dwBlockLength; | ||||
|     unsigned long dwCtrLength; | ||||
| }; | ||||
|  | ||||
| #define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx | ||||
| @@ -299,21 +302,20 @@ struct _libssh2_wincng_cipher_ctx { | ||||
| struct _libssh2_wincng_cipher_type { | ||||
|     BCRYPT_ALG_HANDLE *phAlg; | ||||
|     unsigned long dwKeyLength; | ||||
|     unsigned long dwUseIV; | ||||
|     int useIV; | ||||
|     int ctrMode; | ||||
| }; | ||||
|  | ||||
| #define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type | ||||
|  | ||||
| #define _libssh2_cipher_aes256ctr { NULL, 32, 1 } /* not supported */ | ||||
| #define _libssh2_cipher_aes192ctr { NULL, 24, 1 } /* not supported */ | ||||
| #define _libssh2_cipher_aes128ctr { NULL, 16, 1 } /* not supported */ | ||||
| #define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1 } | ||||
| #define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1 } | ||||
| #define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1 } | ||||
| #define _libssh2_cipher_blowfish { NULL, 16, 0 } /* not supported */ | ||||
| #define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0 } | ||||
| #define _libssh2_cipher_cast5 { NULL, 16, 0 } /* not supported */ | ||||
| #define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1 } | ||||
| #define _libssh2_cipher_aes256ctr { &_libssh2_wincng.hAlgAES_ECB, 32, 0, 1 } | ||||
| #define _libssh2_cipher_aes192ctr { &_libssh2_wincng.hAlgAES_ECB, 24, 0, 1 } | ||||
| #define _libssh2_cipher_aes128ctr { &_libssh2_wincng.hAlgAES_ECB, 16, 0, 1 } | ||||
| #define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1, 0 } | ||||
| #define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1, 0 } | ||||
| #define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1, 0 } | ||||
| #define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0, 0 } | ||||
| #define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1, 0 } | ||||
|  | ||||
| /* | ||||
|  * Windows CNG backend: Cipher functions | ||||
|   | ||||
		Reference in New Issue
	
	Block a user