3434 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3535 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3636 */
37-
37+
3838#include "includes.h"
3939
4040#include <sys/types.h>
4343#include <stdarg.h>
4444#include <stdio.h>
4545
46+
4647#include "cipher.h"
4748#include "misc.h"
4849#include "sshbuf.h"
5152
5253#include "openbsd-compat/openssl-compat.h"
5354
55+
56+
57+ #ifdef USE_MSCNG
58+ #undef WITH_OPENSSL
59+ #endif
60+
5461#ifdef WITH_SSH1
5562extern const EVP_CIPHER * evp_ssh1_bf (void );
5663extern const EVP_CIPHER * evp_ssh1_3des (void );
@@ -108,9 +115,19 @@ static const struct sshcipher ciphers[] = {
108115 SSH_CIPHER_SSH2 , 16 , 32 , 12 , 16 , 0 , 0 , EVP_aes_256_gcm },
109116# endif /* OPENSSL_HAVE_EVPGCM */
110117#else /* WITH_OPENSSL */
118+
119+ #ifdef USE_MSCNG
120+ { "aes128-ctr" , SSH_CIPHER_SSH2 , 16 , 16 , 0 , 0 , 0 , _CNG_CIPHER_AES | _CNG_MODE_CTR , NULL },
121+ { "aes192-ctr" , SSH_CIPHER_SSH2 , 16 , 24 , 0 , 0 , 0 , _CNG_CIPHER_AES | _CNG_MODE_CTR , NULL },
122+ { "aes256-ctr" , SSH_CIPHER_SSH2 , 16 , 32 , 0 , 0 , 0 , _CNG_CIPHER_AES | _CNG_MODE_CTR , NULL },
123+ { "aes128-cbc" , SSH_CIPHER_SSH2 , 16 , 16 , 0 , 0 , 0 , _CNG_CIPHER_AES | _CNG_MODE_CBC , NULL },
124+ { "aes192-cbc" , SSH_CIPHER_SSH2 , 16 , 24 , 0 , 0 , 0 , _CNG_CIPHER_AES | _CNG_MODE_CBC , NULL },
125+ { "aes256-cbc" , SSH_CIPHER_SSH2 , 16 , 32 , 0 , 0 , 0 , _CNG_CIPHER_AES | _CNG_MODE_CBC , NULL },
126+ #else
111127 { "aes128-ctr" , SSH_CIPHER_SSH2 , 16 , 16 , 0 , 0 , 0 , CFLAG_AESCTR , NULL },
112128 { "aes192-ctr" , SSH_CIPHER_SSH2 , 16 , 24 , 0 , 0 , 0 , CFLAG_AESCTR , NULL },
113129 { "aes256-ctr" , SSH_CIPHER_SSH2 , 16 , 32 , 0 , 0 , 0 , CFLAG_AESCTR , NULL },
130+ #endif
114131 { "none" , SSH_CIPHER_NONE , 8 , 0 , 0 , 0 , 0 , CFLAG_NONE , NULL },
115132#endif /* WITH_OPENSSL */
116133 { "chacha20-poly1305@openssh.com" ,
@@ -293,6 +310,8 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
293310 const u_char * key , u_int keylen , const u_char * iv , u_int ivlen ,
294311 int do_encrypt )
295312{
313+
314+
296315#ifdef WITH_OPENSSL
297316 int ret = SSH_ERR_INTERNAL_ERROR ;
298317 const EVP_CIPHER * type ;
@@ -316,11 +335,25 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
316335 return chachapoly_init (& cc -> cp_ctx , key , keylen );
317336 }
318337#ifndef WITH_OPENSSL
338+
339+ #ifdef USE_MSCNG
340+
341+ /* cng shares cipher flag with NONE. Make sure the NONE cipher isn't requested */
342+ if ((cc -> cipher -> flags & CFLAG_NONE ) == 0 )
343+ {
344+
345+ if (cng_cipher_init (& cc -> cng_ctx ,key ,keylen ,iv , ivlen ,cc -> cipher -> flags ))
346+ return SSH_ERR_LIBCRYPTO_ERROR ;
347+
348+ return 0 ;
349+ }
350+ #else
319351 if ((cc -> cipher -> flags & CFLAG_AESCTR ) != 0 ) {
320352 aesctr_keysetup (& cc -> ac_ctx , key , 8 * keylen , 8 * ivlen );
321353 aesctr_ivsetup (& cc -> ac_ctx , iv );
322354 return 0 ;
323355 }
356+ #endif
324357 if ((cc -> cipher -> flags & CFLAG_NONE ) != 0 )
325358 return 0 ;
326359 return SSH_ERR_INVALID_ARGUMENT ;
@@ -373,6 +406,7 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
373406 return 0 ;
374407}
375408
409+
376410/*
377411 * cipher_crypt() operates as following:
378412 * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
@@ -387,18 +421,44 @@ int
387421cipher_crypt (struct sshcipher_ctx * cc , u_int seqnr , u_char * dest ,
388422 const u_char * src , u_int len , u_int aadlen , u_int authlen )
389423{
424+ #ifdef USE_MSCNG
425+ int ret = 0 ;
426+ #endif
427+
390428 if ((cc -> cipher -> flags & CFLAG_CHACHAPOLY ) != 0 ) {
391429 return chachapoly_crypt (& cc -> cp_ctx , seqnr , dest , src ,
392430 len , aadlen , authlen , cc -> encrypt );
393431 }
394432#ifndef WITH_OPENSSL
395- if ((cc -> cipher -> flags & CFLAG_AESCTR ) != 0 ) {
433+
434+ #ifdef USE_MSCNG
435+
436+ /* cng shares cipher flag with NONE. Make sure the NONE cipher isn't requested */
437+ if ((cc -> cipher -> flags & CFLAG_NONE ) == 0 )
438+ {
439+ if (aadlen )
440+ memcpy (dest , src , aadlen );
441+ if (cc -> encrypt )
442+ ret = cng_cipher_encrypt (& cc -> cng_ctx ,dest + aadlen , len , src + aadlen ,len );
443+ else
444+ ret = cng_cipher_decrypt (& cc -> cng_ctx ,dest + aadlen , len , src + aadlen , len );
445+
446+ if (ret != len ){
447+ return SSH_ERR_LIBCRYPTO_ERROR ;
448+ }
449+ return 0 ;
450+ }
451+ #else
452+ if ((cc -> cipher -> flags & CFLAG_AESCTR ) != 0 ) {
396453 if (aadlen )
397454 memcpy (dest , src , aadlen );
398455 aesctr_encrypt_bytes (& cc -> ac_ctx , src + aadlen ,
399456 dest + aadlen , len );
400457 return 0 ;
401458 }
459+ #endif
460+
461+
402462 if ((cc -> cipher -> flags & CFLAG_NONE ) != 0 ) {
403463 memcpy (dest , src , aadlen + len );
404464 return 0 ;
@@ -472,6 +532,10 @@ cipher_cleanup(struct sshcipher_ctx *cc)
472532 else if (EVP_CIPHER_CTX_cleanup (& cc -> evp ) == 0 )
473533 return SSH_ERR_LIBCRYPTO_ERROR ;
474534#endif
535+ #ifdef USE_MSCNG
536+ else
537+ cng_cipher_cleanup (& cc -> cng_ctx );
538+ #endif
475539 return 0 ;
476540}
477541
0 commit comments