CTR and CBC mode CNG ciphers replacing OpenSSL ciphers

This commit is contained in:
arif-pragmasys 2015-10-17 11:09:01 -05:00
parent d59177d82e
commit bafc1df7c5
12 changed files with 612 additions and 119 deletions

3
.gitignore vendored
View File

@ -262,4 +262,5 @@ regress/rsa_ssh2_crnl.prv
regress/t7.out.pub
regress/t6.out2
config.h
configure
configure
config.h

View File

@ -44,7 +44,7 @@ CC=@CC@
LD=@LD@
CFLAGS=@CFLAGS@
CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
LIBS=@LIBS@
LIBS=@LIBS@ -lbcrypt
K5LIBS=@K5LIBS@
GSSLIBS=@GSSLIBS@
SSHLIBS=@SSHLIBS@
@ -58,7 +58,7 @@ PERL=@PERL@
SED=@SED@
ENT=@ENT@
XAUTH_PATH=@XAUTH_PATH@
LDFLAGS=-L. -Lopenbsd-compat/ -Lcontrib/win32/win32compat @LDFLAGS@
LDFLAGS=-L. -Lopenbsd-compat/ -Lcontrib/win32/win32compat @LDFLAGS@ -L/cygdrive/C/cygwin-32/lib/w32api
EXEEXT=@EXEEXT@
MANFMT=@MANFMT@

View File

@ -34,7 +34,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
@ -43,6 +43,7 @@
#include <stdarg.h>
#include <stdio.h>
#include "cipher.h"
#include "misc.h"
#include "sshbuf.h"
@ -51,6 +52,12 @@
#include "openbsd-compat/openssl-compat.h"
#ifdef USE_MSCNG
#undef WITH_OPENSSL
#endif
#ifdef WITH_SSH1
extern const EVP_CIPHER *evp_ssh1_bf(void);
extern const EVP_CIPHER *evp_ssh1_3des(void);
@ -108,9 +115,19 @@ static const struct sshcipher ciphers[] = {
SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
# endif /* OPENSSL_HAVE_EVPGCM */
#else /* WITH_OPENSSL */
#ifdef USE_MSCNG
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, _CNG_CIPHER_AES | _CNG_MODE_CTR, NULL },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, _CNG_CIPHER_AES | _CNG_MODE_CTR, NULL },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, _CNG_CIPHER_AES | _CNG_MODE_CTR, NULL },
{ "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, _CNG_CIPHER_AES | _CNG_MODE_CBC, NULL },
{ "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, _CNG_CIPHER_AES | _CNG_MODE_CBC, NULL },
{ "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, _CNG_CIPHER_AES | _CNG_MODE_CBC, NULL },
#else
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL },
#endif
{ "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL },
#endif /* WITH_OPENSSL */
{ "chacha20-poly1305@openssh.com",
@ -293,6 +310,8 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
int do_encrypt)
{
#ifdef WITH_OPENSSL
int ret = SSH_ERR_INTERNAL_ERROR;
const EVP_CIPHER *type;
@ -316,11 +335,25 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
return chachapoly_init(&cc->cp_ctx, key, keylen);
}
#ifndef WITH_OPENSSL
#ifdef USE_MSCNG
/* cng shares cipher flag with NONE. Make sure the NONE cipher isn't requested */
if ((cc->cipher->flags & CFLAG_NONE) == 0)
{
if (cng_cipher_init(&cc->cng_ctx,key,keylen,iv, ivlen,cc->cipher->flags))
return SSH_ERR_LIBCRYPTO_ERROR;
return 0;
}
#else
if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
aesctr_ivsetup(&cc->ac_ctx, iv);
return 0;
}
#endif
if ((cc->cipher->flags & CFLAG_NONE) != 0)
return 0;
return SSH_ERR_INVALID_ARGUMENT;
@ -373,6 +406,7 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
return 0;
}
/*
* cipher_crypt() operates as following:
* Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
@ -387,18 +421,44 @@ int
cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
const u_char *src, u_int len, u_int aadlen, u_int authlen)
{
#ifdef USE_MSCNG
int ret = 0;
#endif
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src,
len, aadlen, authlen, cc->encrypt);
}
#ifndef WITH_OPENSSL
if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
#ifdef USE_MSCNG
/* cng shares cipher flag with NONE. Make sure the NONE cipher isn't requested */
if ((cc->cipher->flags & CFLAG_NONE) == 0)
{
if (aadlen)
memcpy(dest, src, aadlen);
if (cc->encrypt)
ret = cng_cipher_encrypt(&cc->cng_ctx,dest+aadlen, len, src+aadlen,len);
else
ret = cng_cipher_decrypt(&cc->cng_ctx,dest+aadlen, len, src+aadlen, len);
if (ret != len){
return SSH_ERR_LIBCRYPTO_ERROR;
}
return 0;
}
#else
if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
if (aadlen)
memcpy(dest, src, aadlen);
aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen,
dest + aadlen, len);
return 0;
}
#endif
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
memcpy(dest, src, aadlen + len);
return 0;
@ -472,6 +532,10 @@ cipher_cleanup(struct sshcipher_ctx *cc)
else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
return SSH_ERR_LIBCRYPTO_ERROR;
#endif
#ifdef USE_MSCNG
else
cng_cipher_cleanup(&cc->cng_ctx);
#endif
return 0;
}

View File

@ -41,7 +41,9 @@
#include <openssl/evp.h>
#include "cipher-chachapoly.h"
#include "cipher-aesctr.h"
#ifdef USE_MSCNG
#include "contrib/win32/win32compat/cng_cipher.h"
#endif
/*
* Cipher types for SSH-1. New types can be added, but old types should not
* be removed for compatibility. The maximum allowed value is 31.
@ -70,6 +72,10 @@ struct sshcipher_ctx {
struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
struct aesctr_ctx ac_ctx; /* XXX union with evp? */
const struct sshcipher *cipher;
#ifdef USE_MSCNG
struct ssh_cng_cipher_ctx cng_ctx;
#endif
};
u_int cipher_mask_ssh1(int);

211
config.h
View File

@ -83,7 +83,7 @@
/* #undef BSD_AUTH */
/* Define if you want to specify the path to your lastlog file */
/* #undef CONF_LASTLOG_FILE */
#define CONF_LASTLOG_FILE "/var/log/lastlog"
/* Define if you want to specify the path to your utmp file */
#define CONF_UTMP_FILE "/var/run/utmp"
@ -1540,107 +1540,108 @@
/* type to use in place of socklen_t if not defined */
/* #undef socklen_t */
#define WIN32_LEAN_AND_MEAN 1
#define _CRT_SECURE_NO_DEPRECATE 1
#define _CRT_NONSTDC_NO_DEPRECATE 1
#define WIN32_FIXME 1
#undef USE_NTCREATETOKEN
/* Define if you must implement a startup_needs function for your platform */
#define HAVE_STARTUP_NEEDS 1
/* Define if your platform uses Winsock instead of BSD sockets (yeah, there are a lot of platforms like this :) */
#define HAVE_WINSOCK 1
#define snprintf _snprintf
#define BROKEN_READV_COMPARISON
/* Override detection of some headers and functions on MinGW */
#undef BROKEN_SNPRINTF
#define GETPGRP_VOID 1
#undef HAVE_CRYPT_H
#define HAVE_DAEMON 1
#undef HAVE_ENDIAN_H
#undef HAVE_FCNTL_H
#define HAVE_FREEADDRINFO 1
#define HAVE_GAI_STRERROR 1
#define HAVE_GETADDRINFO 1
#define HAVE_GETGROUPLIST 1
#define HAVE_GETNAMEINFO 1
#undef HAVE_ID_IN_UTMPX
#define HAVE_INET_ATON 1
#define HAVE_INET_NTOA 1
#define HAVE_INNETGR 1
#undef HAVE_LIBCRYPT
#define HAVE_MKDTEMP 1
#define HAVE_NANOSLEEP 1
#undef HAVE_PATHS_H
#undef HAVE_POLL_H
#undef HAVE_PROC_PID
#undef HAVE_PTY_H
#define HAVE_NANOSLEEP 1
#define HAVE_READPASSPHRASE 1
#define HAVE_REALPATH 1
#undef HAVE_SIG_ATOMIC_T
#define HAVE_SIZE_T 1
#undef HAVE_STRERROR
#define HAVE_STRMODE 1
#undef __USE_W32_SOCKETS
#ifdef __MINGW32__ /* FIXME: Use autoconf to set this correctly */
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the `strncasecmp' function. */
#define HAVE_STRNCASECMP 1
#endif
#define HAVE_STRUCT_IN6_ADDR 1
#define HAVE_STRUCT_SOCKADDR_IN6 1
#define HAVE_STRUCT_TIMEVAL 1
#undef HAVE_SYS_CDEFS_H
#undef HAVE_SYS_SYSMACROS_H
#undef HAVE_SYS_MMAN_H
#undef HAVE_SYS_UN_H
#define HAVE_TCGETPGRP 1
#undef HAVE_TIME
#define HAVE_TRUNCATE 1
#define HAVE_VIS_H 1
#define MISSING_FD_MASK 1
#define MISSING_HOWMANY 1
#define MISSING_NFDBITS 1
#undef SSH_PRIVSEP_USER
#define HAVE_OPENPTY 1
/* Fixes for loginrec.c */
#undef CONF_UTMP_FILE
#undef CONF_WTMPX_FILE
#undef CONF_WTMP_FILE
#undef CONF_UTMPX_FILE
#undef CONF_LASTLOG_FILE
#define BROKEN_SYS_TERMIO_H
#define strerror strerror_win32
#define strerror strerror_win32
// PRAGMA SYS PORT
#define WITH_OPENSSL 1
#define HAVE_KRB5_GET_ERROR_MESSAGE 1
#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
#define HAVE_DECL_NFDBITS 0
#define HAVE_DECL_HOWMANY 0
#define WIN32_ZLIB_NO 1
//#define HAVE_ARC4RANDOM_UNIFORM 1
#define WIN32_LEAN_AND_MEAN 1
#define _CRT_SECURE_NO_DEPRECATE 1
#define _CRT_NONSTDC_NO_DEPRECATE 1
#define WIN32_FIXME 1
#undef USE_NTCREATETOKEN
/* Define if you must implement a startup_needs function for your platform */
#define HAVE_STARTUP_NEEDS 1
/* Define if your platform uses Winsock instead of BSD sockets (yeah, there are a lot of platforms like this :) */
#define HAVE_WINSOCK 1
#define snprintf _snprintf
#define BROKEN_READV_COMPARISON
/* Override detection of some headers and functions on MinGW */
#undef BROKEN_SNPRINTF
#define GETPGRP_VOID 1
#undef HAVE_CRYPT_H
#define HAVE_DAEMON 1
#undef HAVE_ENDIAN_H
#undef HAVE_FCNTL_H
#define HAVE_FREEADDRINFO 1
#define HAVE_GAI_STRERROR 1
#define HAVE_GETADDRINFO 1
#define HAVE_GETGROUPLIST 1
#define HAVE_GETNAMEINFO 1
#undef HAVE_ID_IN_UTMPX
#define HAVE_INET_ATON 1
#define HAVE_INET_NTOA 1
#define HAVE_INNETGR 1
#undef HAVE_LIBCRYPT
#define HAVE_MKDTEMP 1
#define HAVE_NANOSLEEP 1
#undef HAVE_PATHS_H
#undef HAVE_POLL_H
#undef HAVE_PROC_PID
#undef HAVE_PTY_H
#define HAVE_NANOSLEEP 1
#define HAVE_READPASSPHRASE 1
#define HAVE_REALPATH 1
#undef HAVE_SIG_ATOMIC_T
#define HAVE_SIZE_T 1
#undef HAVE_STRERROR
#define HAVE_STRMODE 1
#undef __USE_W32_SOCKETS
#ifdef __MINGW32__ /* FIXME: Use autoconf to set this correctly */
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the `strncasecmp' function. */
#define HAVE_STRNCASECMP 1
#endif
#define HAVE_STRUCT_IN6_ADDR 1
#define HAVE_STRUCT_SOCKADDR_IN6 1
#define HAVE_STRUCT_TIMEVAL 1
#undef HAVE_SYS_CDEFS_H
#undef HAVE_SYS_SYSMACROS_H
#undef HAVE_SYS_MMAN_H
#undef HAVE_SYS_UN_H
#define HAVE_TCGETPGRP 1
#undef HAVE_TIME
#define HAVE_TRUNCATE 1
#define HAVE_VIS_H 1
#define MISSING_FD_MASK 1
#define MISSING_HOWMANY 1
#define MISSING_NFDBITS 1
#undef SSH_PRIVSEP_USER
#define HAVE_OPENPTY 1
/* Fixes for loginrec.c */
#undef CONF_UTMP_FILE
#undef CONF_WTMPX_FILE
#undef CONF_WTMP_FILE
#undef CONF_UTMPX_FILE
#undef CONF_LASTLOG_FILE
#define BROKEN_SYS_TERMIO_H
#define strerror strerror_win32
#define strerror strerror_win32
// PRAGMA SYS PORT
#define WITH_OPENSSL 1
#define HAVE_KRB5_GET_ERROR_MESSAGE 1
#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
#define HAVE_DECL_NFDBITS 0
#define HAVE_DECL_HOWMANY 0
#define WIN32_ZLIB_NO 1
#define USE_MSCNG 1
//#define HAVE_ARC4RANDOM_UNIFORM 1

View File

@ -99,6 +99,7 @@
#define HAVE_DECL_HOWMANY 0
#define WIN32_ZLIB_NO 1
#define USE_MSCNG 1
//#define HAVE_ARC4RANDOM_UNIFORM 1

View File

@ -8,25 +8,32 @@ top_srcdir=@top_srcdir@
VPATH=@srcdir@
CC=@CC@
LD=@LD@
CFLAGS=@CFLAGS@
CPPFLAGS=-I. -I../../.. -I$(srcdir) -I$(top_srcdir) -I$(srcdir)/includes @CPPFLAGS@ @DEFS@
LIBS=@LIBS@
BCRYPTFLAGS=-I/usr/include/w32api
CFLAGS=@CFLAGS@
CPPFLAGS=-I. -I../../.. -I$(srcdir) -I$(top_srcdir) -I$(srcdir)/includes @CPPFLAGS@ @DEFS@ -DUSE_MSCNG
LIBS=@LIBS@ -lbcrypt
AR=@AR@
RANLIB=@RANLIB@
INSTALL=@INSTALL@
LDFLAGS=-L. @LDFLAGS@
LDFLAGS=-L. @LDFLAGS@ -L/lib/win32api
WIN32COMPATFILES = daemon.o gettimeofday.o homedirhelp.o pwd.o sfds.o \
socket.o startupneeds.o strcasecmp.o syslog.o lsalogon.o lsastring.o \
stringhelp.o deskright.o win32auth.o kerberos.o ansiprsr.o console.o tnnet.o
stringhelp.o deskright.o win32auth.o kerberos.o cng_cipher.o ansiprsr.o console.o tnnet.o
WIN32COMPATLIB=@LIBWIN32COMPAT@
CNGFILES=cng_cipher.o
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
all: $(WIN32COMPATLIB)
$(CNGFILES): %.o: %.c
$(CC) $(CFLAGS) $(BCRYPTFLAGS) $(CPPFLAGS) -c $<
install:
clean:

View File

@ -0,0 +1,298 @@
/* cng_cipher.c
* Author: Pragma Systems, Inc. <www.pragmasys.com>
* Contribution by Pragma Systems, Inc. for Microsoft openssh win32 port
* Copyright (c) 2011, 2015 Pragma Systems, Inc.
* All rights reserved
*
* Common library for Windows Console Screen IO.
* Contains Windows console related definition so that emulation code can draw
* on Windows console screen surface.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice.
* 2. Binaries produced provide no direct or implied warranties or any
* guarantee of performance or suitability.
*/
#include <Windows.h>
#include <bcrypt.h>
#include "cng_cipher.h"
#ifdef USE_MSCNG
#define AES_BLOCK_SIZE 16
/*
* increment the aes counter (iv)
*/
static void aesctr_inc(unsigned char *ctr, unsigned int len)
{
size_t i;
#ifndef CONSTANT_TIME_INCREMENT
for (i = len - 1; i >= 0; i--)
if (++ctr[i]) /* continue on overflow */
return;
#else
u8 x, add = 1;
for (i = len - 1; i >= 0; i--) {
ctr[i] += add;
/* constant time for: x = ctr[i] ? 1 : 0 */
x = ctr[i];
x = (x | (x >> 4)) & 0xf;
x = (x | (x >> 2)) & 0x3;
x = (x | (x >> 1)) & 0x1;
add *= (x ^ 1);
}
#endif
}
/*
* Routine to encrypt a counter for ctr encryption. This requries
* us to use an IV that is reset for each call to avoid cng attempting
* to chain encryptions.
*/
DWORD cng_counter_encrypt(const unsigned char *in, unsigned char *out, BCRYPT_KEY_HANDLE key, unsigned int blocklen)
{
HRESULT status = S_OK;
DWORD cbResult = 0;
unsigned char iv[AES_BLOCK_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
status = BCryptEncrypt(
key,
(PUCHAR)in,
blocklen,
NULL,
iv,
blocklen,
out,
blocklen,
&cbResult,
0);
return cbResult;
}
/*
* Encrypt/Decrypt data using a CTR mode.
* In this mode, we can't call CNG encryption/decription directly. The mode requires
* the use of the iv as a counter that is incremented and encrypted. The
* encrypted counter is then XORd with the data to produce the cipher text.
*/
int cng_aesctr_encrypt_bytes(PSSH_CNG_CIPHER_CTX x, const unsigned char *m, unsigned char *c, unsigned int bytes)
{
int ret = 0;
unsigned int n = 0;
unsigned char buf[AES_BLOCK_SIZE];
while ((bytes--) > 0) {
if (n == 0) {
if (!cng_counter_encrypt(x->pbIV, buf, x->hKey, AES_BLOCK_SIZE))
{
ret = -1;
break;
}
aesctr_inc(x->pbIV, AES_BLOCK_SIZE);
}
*(c++) = *(m++) ^ buf[n];
n = (n + 1) % AES_BLOCK_SIZE;
}
return ret;
}
/*
* Encrypt data using a provided cipher context
*/
unsigned int cng_cipher_encrypt(PSSH_CNG_CIPHER_CTX x, unsigned char *dest, unsigned int dest_len, const unsigned char *src, unsigned int len)
{
DWORD cbResult = 0;
HRESULT status = S_OK;
if (x->flags & _CNG_MODE_CTR)
{
if (-1 == cng_aesctr_encrypt_bytes(x, src, dest, len))
{
status = GetLastError();
}
cbResult = len;
}
else
{
status = BCryptEncrypt(
x->hKey,
(PUCHAR)src,
len,
NULL,
x->pbIV,
x->cbBlockSize,
dest,
dest_len,
&cbResult,
0);
if (S_OK != status)
{
cbResult = 0;
SetLastError(status);
}
}
return cbResult;
}
/*
* Decrypt encrypted data using a provided cipher context
*/
unsigned int cng_cipher_decrypt(PSSH_CNG_CIPHER_CTX x, unsigned char *dest, unsigned int dest_len, const unsigned char *src, unsigned int len)
{
DWORD cbResult = 0;
HRESULT status = S_OK;
if (x->flags & _CNG_MODE_CTR)
{
// ctr mode is just an XOR so encrypt=decrypt
if (-1 == cng_aesctr_encrypt_bytes(x, src, dest, len))
{
status = GetLastError();
}
cbResult = len;
}
else
{
status = BCryptDecrypt(
x->hKey,
(PUCHAR)src,
len,
NULL,
x->pbIV,
x->cbBlockSize,
dest,
dest_len,
&cbResult,
0);
if (S_OK != status)
{
cbResult = 0;
SetLastError(status);
}
}
return cbResult;
}
/*
* Initialize cipher context
*/
unsigned int cng_cipher_init(PSSH_CNG_CIPHER_CTX x, const unsigned char *key, unsigned int keylen, const unsigned char *iv, size_t ivlen, unsigned int flags)
{
HRESULT status = S_OK;
BCRYPT_ALG_HANDLE hAlg = NULL;
DWORD cbData = 0;
LPCWSTR pAlg = NULL;
DWORD cbBlockLen = 0;
if ((0 == (flags & _CNG_CIPHER_AES)) || (0 == (flags & (_CNG_MODE_CBC | _CNG_MODE_CTR))))
return STATUS_INVALID_PARAMETER;
// wipe out old context
memset(x, 0, sizeof(SSH_CNG_CIPHER_CTX));
// initialize simple context fields
x->flags = flags;
// only one cipher supported right now
if (flags & _CNG_CIPHER_AES)
pAlg = BCRYPT_AES_ALGORITHM;
// Generate BCrypt Key and set mode if applicable
if (NT_SUCCESS(status = BCryptOpenAlgorithmProvider(
&hAlg,
pAlg,
NULL,
0)))
{
if (NT_SUCCESS(status = BCryptGetProperty(
hAlg,
BCRYPT_BLOCK_LENGTH,
(PBYTE)&cbBlockLen,
sizeof(DWORD),
&cbData,
0)))
{
x->cbBlockSize = cbBlockLen;
if (cbBlockLen != ivlen)
{
status = STATUS_INVALID_PARAMETER;
}
else
{
x->pbIV = (PBYTE)HeapAlloc(GetProcessHeap(), 0, ivlen);
if (NULL == x->pbIV)
{
status = GetLastError();
}
else
{
memcpy(x->pbIV, iv, ivlen);
}
}
}
if (status == S_OK && flags & _CNG_MODE_CBC)
{
status = BCryptSetProperty(
hAlg,
BCRYPT_CHAINING_MODE,
(PBYTE)BCRYPT_CHAIN_MODE_CBC,
sizeof(BCRYPT_CHAIN_MODE_CBC),
0);
}
if (status == S_OK)
{
status = BCryptGenerateSymmetricKey(
hAlg,
&(x->hKey),
NULL,
0,
(PBYTE)key,
keylen,
0);
}
BCryptCloseAlgorithmProvider(hAlg, 0);
// if we got an error along the way, free up the iv
if (status != S_OK && x->pbIV)
{
HeapFree(GetProcessHeap(), 0, x->pbIV);
}
}
return status;
}
/*
* Cleanup cipher context fields
*/
void cng_cipher_cleanup(PSSH_CNG_CIPHER_CTX x)
{
if (x->pbIV)
HeapFree(GetProcessHeap(), 0, x->pbIV);
if (x->hKey)
BCryptDestroyKey(x->hKey);
}
#endif

View File

@ -0,0 +1,64 @@
/* cng_cipher.h
* Author: Pragma Systems, Inc. <www.pragmasys.com>
* Contribution by Pragma Systems, Inc. for Microsoft openssh win32 port
* Copyright (c) 2011, 2015 Pragma Systems, Inc.
* All rights reserved
*
* Common library for Windows Console Screen IO.
* Contains Windows console related definition so that emulation code can draw
* on Windows console screen surface.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice.
* 2. Binaries produced provide no direct or implied warranties or any
* guarantee of performance or suitability.
*/
#ifndef CNG_CIPHER_H
#define CNG_CIPHER_H
#ifdef USE_MSCNG
#ifdef __cplusplus
extern "C" {
#endif
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
/* CIPHER/MODE bits specify cipher and mode in the flags
* field of the context
*/
#define _CNG_CIPHER_AES 0x00000001
#define _CNG_MODE_CTR 0x00010000
#define _CNG_MODE_CBC 0x00020000
#define _CNG_CIPHER_MASK 0x0000FFFF
#define _CNG_MODE_MASK 0xFFFF0000
typedef struct ssh_cng_cipher_ctx
{
void * hKey;
unsigned char * pbIV;
unsigned int cbBlockSize;
unsigned int flags;
} SSH_CNG_CIPHER_CTX, *PSSH_CNG_CIPHER_CTX;
unsigned int cng_cipher_encrypt(PSSH_CNG_CIPHER_CTX x, unsigned char *dest, unsigned int dest_len, const unsigned char *src, unsigned int len);
unsigned int cng_cipher_decrypt(PSSH_CNG_CIPHER_CTX x, unsigned char *dest, unsigned int dest_len, const unsigned char *src, unsigned int len);
unsigned int cng_cipher_init(PSSH_CNG_CIPHER_CTX x, const unsigned char *key, unsigned int keylen, const unsigned char *iv, size_t ivlen, unsigned int flags);
void cng_cipher_cleanup(PSSH_CNG_CIPHER_CTX x);
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@ -0,0 +1 @@
!<arch>

View File

@ -0,0 +1,50 @@
# $Id $
sysconfdir=${prefix}/etc
piddir=/var/run
srcdir=.
top_srcdir=../../..
CC=i686-pc-mingw32-gcc
LD=i686-pc-mingw32-gcc
CFLAGS=-g -O2 -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -fno-builtin-memset -I/cygdrive/c/openssh/Win32-OpenSSH/contrib/win32/win32compat/includes -I/cygdrive/c/openssh/Win32-OpenSSH/openbsd-compat -I/cygdrive/c/openssh/Win32-OpenSSH/contrib/win32/win32compat/includes -I/cygdrive/c/openssh/Win32-OpenSSH/libkrb -I/usr/local
BCRYPTFLAGS=-I/usr/include/w32api
CPPFLAGS=-I. -I../../.. -I$(srcdir) -I$(top_srcdir) -I$(srcdir)/includes -I/cygdrive/c/openssh/Win32-OpenSSH/../openssl-1.0.2d/include -DHAVE_CONFIG_H -DUSE_MSCNG
LIBS=-lcrypto -lz -lws2_32 -lgdi32 -lNetAPI32 -luserenv -lsecur32 -lshlwapi -lbcrypt
AR=/usr/bin/ar
RANLIB=i686-pc-mingw32-ranlib
INSTALL=/usr/bin/install -c
LDFLAGS=-L. -L/cygdrive/c/openssh/Win32-OpenSSH/../openssl-1.0.2d -L/lib/win32api
WIN32COMPATFILES = daemon.o gettimeofday.o homedirhelp.o pwd.o sfds.o \
socket.o startupneeds.o strcasecmp.o syslog.o lsalogon.o lsastring.o \
stringhelp.o deskright.o win32auth.o kerberos.o cng_cipher.o ansiprsr.o console.o tnnet.o
WIN32COMPATLIB=libwin32compat.a
CNGFILES=cng_cipher.o
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
all: $(WIN32COMPATLIB)
$(CNGFILES): %.o: %.c
$(CC) $(CFLAGS) $(BCRYPTFLAGS) $(CPPFLAGS) -c $<
install:
clean:
rm -f *.o *.a core
distclean: clean
rm -f Makefile *~
$(WIN32COMPATFILES): ../../../config.h
$(WIN32COMPATLIB): $(WIN32COMPATFILES)
$(AR) rv $@ $(WIN32COMPATFILES)
$(RANLIB) $@

View File

@ -8,12 +8,12 @@ top_srcdir=../..
CC=i686-pc-mingw32-gcc
LD=i686-pc-mingw32-gcc
CFLAGS=-g -O2 -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -fno-builtin-memset -fstack-protector-all -I/cygdrive/c/openssh/Win32-OpenSSH/contrib/win32/win32compat/includes -I/cygdrive/c/openssh/Win32-OpenSSH/openbsd-compat -I/cygdrive/c/openssh/Win32-OpenSSH/contrib/win32/win32compat/includes -I/cygdrive/c/openssh/Win32-OpenSSH/libkrb -I/usr/local
CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. -I/cygdrive/c/openssh/openssl-1.0.2d/include -I/cygdrive/c/openssh/zlib-1.2.8 -DHAVE_CONFIG_H
CFLAGS=-g -O2 -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -fno-builtin-memset -I/cygdrive/c/openssh/Win32-OpenSSH/contrib/win32/win32compat/includes -I/cygdrive/c/openssh/Win32-OpenSSH/openbsd-compat -I/cygdrive/c/openssh/Win32-OpenSSH/contrib/win32/win32compat/includes -I/cygdrive/c/openssh/Win32-OpenSSH/libkrb -I/usr/local
CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. -I/cygdrive/c/openssh/Win32-OpenSSH/../openssl-1.0.2d/include -DHAVE_CONFIG_H
EXEEXT=.exe
LIBCOMPAT=../libopenbsd-compat.a
LIBS=-lcrypto -lz -lws2_32 -lgdi32 -lNetAPI32 -luserenv -lsecur32 -lshlwapi
LDFLAGS=-L/cygdrive/c/openssh/openssl-1.0.2d -L/cygdrive/c/openssh/zlib-1.2.8 -fstack-protector-all $(LIBCOMPAT)
LDFLAGS=-L/cygdrive/c/openssh/Win32-OpenSSH/../openssl-1.0.2d $(LIBCOMPAT)
TESTPROGS=closefromtest$(EXEEXT) snprintftest$(EXEEXT) strduptest$(EXEEXT) \
strtonumtest$(EXEEXT) opensslvertest$(EXEEXT)