static int aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) { BCRYPT_ALG_HANDLE hAlg; BCRYPT_KEY_HANDLE hKey; DWORD keyObj_len, aes_key_len; PBYTE keyObj; ULONG result; NTSTATUS status; BCRYPT_KEY_LENGTHS_STRUCT key_lengths; ctx->hAlg = NULL; ctx->hKey = NULL; ctx->keyObj = NULL; switch (key_len) { case 16: aes_key_len = 128; break; case 24: aes_key_len = 192; break; case 32: aes_key_len = 256; break; default: return -1; } status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths, sizeof(key_lengths), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } if (key_lengths.dwMinLength > aes_key_len || key_lengths.dwMaxLength < aes_key_len) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len, sizeof(keyObj_len), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len); if (keyObj == NULL) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, keyObj); return -1; } status = BCryptGenerateSymmetricKey(hAlg, &hKey, keyObj, keyObj_len, (PUCHAR)(uintptr_t)key, (ULONG)key_len, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, keyObj); return -1; } ctx->hAlg = hAlg; ctx->hKey = hKey; ctx->keyObj = keyObj; ctx->keyObj_len = keyObj_len; ctx->encr_pos = AES_BLOCK_SIZE; return 0; }
int _libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen, unsigned char *key, unsigned long keylen) { BCRYPT_HASH_HANDLE hHash; unsigned char *pbHashObject; unsigned long dwHashObject, dwHash, cbData; int ret; ret = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (unsigned char *)&dwHash, sizeof(dwHash), &cbData, 0); if ((!BCRYPT_SUCCESS(ret)) || dwHash != hashlen) { return -1; } ret = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (unsigned char *)&dwHashObject, sizeof(dwHashObject), &cbData, 0); if (!BCRYPT_SUCCESS(ret)) { return -1; } pbHashObject = malloc(dwHashObject); if (!pbHashObject) { return -1; } ret = BCryptCreateHash(hAlg, &hHash, pbHashObject, dwHashObject, key, keylen, 0); if (!BCRYPT_SUCCESS(ret)) { free(pbHashObject); return -1; } ctx->hHash = hHash; ctx->pbHashObject = pbHashObject; ctx->dwHashObject = dwHashObject; ctx->cbHash = dwHash; return 0; }
MicrosoftCryptoProvider::MicrosoftCryptoProvider() : m_hProvider(0) { #if defined(USE_MS_CRYPTOAPI) // See http://support.microsoft.com/en-us/kb/238187 for CRYPT_NEWKEYSET fallback strategy if (!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { const DWORD firstErr = GetLastError(); if (!CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET /*user*/) && !CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET)) { // Set original error with original code SetLastError(firstErr); throw OS_RNG_Err("CryptAcquireContext"); } } #elif defined(USE_MS_CNGAPI) NTSTATUS ret = BCryptOpenAlgorithmProvider(&m_hProvider, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); if (!(BCRYPT_SUCCESS(ret))) { // Hack... OS_RNG_Err calls GetLastError() SetLastError(NtStatusToErrorCode(ret)); throw OS_RNG_Err("BCryptOpenAlgorithmProvider"); } #endif }
void NonblockingRng::GenerateBlock(byte *output, size_t size) { #ifdef CRYPTOPP_WIN32_AVAILABLE // Acquiring a provider is expensive. Do it once and retain the reference. static const MicrosoftCryptoProvider &hProvider = Singleton<MicrosoftCryptoProvider>().Ref(); # if defined(USE_MS_CRYPTOAPI) if (!CryptGenRandom(hProvider.GetProviderHandle(), (DWORD)size, output)) throw OS_RNG_Err("CryptGenRandom"); # elif defined(USE_MS_CNGAPI) NTSTATUS ret = BCryptGenRandom(hProvider.GetProviderHandle(), output, (ULONG)size, 0); if (!(BCRYPT_SUCCESS(ret))) { // Hack... OS_RNG_Err calls GetLastError() SetLastError(NtStatusToErrorCode(ret)); throw OS_RNG_Err("BCryptGenRandom"); } # endif #else while (size) { ssize_t len = read(m_fd, output, size); if (len < 0) { // /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well) if (errno != EINTR && errno != EAGAIN) throw OS_RNG_Err("read /dev/urandom"); continue; } output += len; size -= len; } #endif // CRYPTOPP_WIN32_AVAILABLE }
int _libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsa, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) { BCRYPT_PKCS1_PADDING_INFO paddingInfo; unsigned char *data, *sig; unsigned long cbData, datalen, siglen; int ret; datalen = (unsigned long)hash_len; data = malloc(datalen); if (!data) { return -1; } paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM; memcpy(data, hash, datalen); ret = BCryptSignHash(rsa->hKey, &paddingInfo, data, datalen, NULL, 0, &cbData, BCRYPT_PAD_PKCS1); if (BCRYPT_SUCCESS(ret)) { siglen = cbData; sig = LIBSSH2_ALLOC(session, siglen); if (sig) { ret = BCryptSignHash(rsa->hKey, &paddingInfo, data, datalen, sig, siglen, &cbData, BCRYPT_PAD_PKCS1); if (BCRYPT_SUCCESS(ret)) { *signature_len = siglen; *signature = sig; } else { LIBSSH2_FREE(session, sig); } } else ret = STATUS_NO_MEMORY; } free(data); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
int _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), int encrypt, unsigned char *block, size_t blocklen) { unsigned char *pbOutput; unsigned long cbOutput, cbInput; int ret; (void)type; cbInput = (unsigned long)blocklen; if (encrypt) { ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); } else { ret = BCryptDecrypt(ctx->hKey, block, 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, ctx->pbIV, ctx->dwIV, pbOutput, cbOutput, &cbOutput, 0); } else { ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, ctx->pbIV, ctx->dwIV, pbOutput, cbOutput, &cbOutput, 0); } if (BCRYPT_SUCCESS(ret)) { memcpy(block, pbOutput, cbOutput); } free(pbOutput); } else ret = STATUS_NO_MEMORY; } return BCRYPT_SUCCESS(ret) ? 0 : -1; }
static void read_entropy(uint8_t *entropy, size_t size) { NTSTATUS nts = 0; BCRYPT_ALG_HANDLE hAlgorithm = 0; nts = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(nts)) { nts = BCryptGenRandom(hAlgorithm, (PUCHAR)entropy, (ULONG)size, 0); (void)BCryptCloseAlgorithmProvider(hAlgorithm, 0); } if (!BCRYPT_SUCCESS(nts)) { perror("ptls_minicrypto_random_bytes: could not open BCrypt RNG Algorithm"); abort(); } }
int _libssh2_wincng_random(void *buf, int len) { int ret; ret = BCryptGenRandom(_libssh2_wincng.hAlgRNG, buf, len, 0); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
int _libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, const unsigned char *data, unsigned long datalen) { int ret; ret = BCryptHashData(ctx->hHash, (unsigned char *)data, datalen, 0); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
int _libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, unsigned char *hash) { int ret; ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) { #pragma GCC diagnostic ignored "-Wcast-qual" BCRYPT_ALG_HANDLE hAlg; BCRYPT_HASH_HANDLE hHash; DWORD hash_len; PBYTE hash; ULONG result; NTSTATUS status; ctx->hAlg = NULL; status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len, sizeof(hash_len), &result, 0); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len); if (hash == NULL) { BCryptCloseAlgorithmProvider(hAlg, 0); return -1; } status = BCryptCreateHash(hAlg, &hHash, NULL, 0, (PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG); if (!BCRYPT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); HeapFree(GetProcessHeap(), 0, hash); return -1; } ctx->hAlg = hAlg; ctx->hHash = hHash; ctx->hash_len = hash_len; ctx->hash = hash; return 0; }
int _libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa, const unsigned char *hash, unsigned long hash_len, unsigned char *sig_fixed) { unsigned char *data, *sig; unsigned long cbData, datalen, siglen; int ret; datalen = hash_len; data = malloc(datalen); if (!data) { return -1; } memcpy(data, hash, datalen); ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, NULL, 0, &cbData, 0); if (BCRYPT_SUCCESS(ret)) { siglen = cbData; if (siglen == 40) { sig = malloc(siglen); if (sig) { ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, sig, siglen, &cbData, 0); if (BCRYPT_SUCCESS(ret)) { memcpy(sig_fixed, sig, siglen); } free(sig); } else ret = STATUS_NO_MEMORY; } else ret = STATUS_NO_MEMORY; } free(data); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { NTSTATUS status; ULONG result; status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE, NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE, &result, 0); return BCRYPT_SUCCESS(status) ? 0 : -1; }
static int pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len) { NTSTATUS status; BCRYPT_ALG_HANDLE hAlg; status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!BCRYPT_SUCCESS(status)) return -1; status = BCryptDeriveKeyPBKDF2(hAlg, (PUCHAR)(uintptr_t)pw, (ULONG)pw_len, (PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds, (PUCHAR)derived_key, (ULONG)derived_key_len, 0); BCryptCloseAlgorithmProvider(hAlg, 0); return (BCRYPT_SUCCESS(status)) ? 0: -1; }
void _libssh2_wincng_init(void) { int ret; (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG, BCRYPT_RNG_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5, BCRYPT_MD5_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1, BCRYPT_SHA1_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5, BCRYPT_MD5_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA, BCRYPT_RSA_ALGORITHM, NULL, 0); (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA, BCRYPT_DSA_ALGORITHM, NULL, 0); ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC, BCRYPT_AES_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, BCRYPT_RC4_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_NA, sizeof(BCRYPT_CHAIN_MODE_NA), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC, BCRYPT_3DES_ALGORITHM, NULL, 0); if (BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if (!BCRYPT_SUCCESS(ret)) { (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); } } }
int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen) { ((void)data); *olen = 0; /* * size_t may be 64 bits, but ULONG is always 32. * If len is larger than the maximum for ULONG, just fail. * It's unlikely anything ever will want to ask for this much randomness. */ if (len > 0xFFFFFFFFULL) { return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); } if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, (ULONG) len, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); } *olen = len; return (0); }
int _libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *gdata, unsigned long glen, const unsigned char *ydata, unsigned long ylen, const unsigned char *xdata, unsigned long xlen) { BCRYPT_KEY_HANDLE hKey; BCRYPT_DSA_KEY_BLOB *dsakey; LPCWSTR lpszBlobType; unsigned char *key; unsigned long keylen, offset, length; int ret; length = max(max(_libssh2_wincng_bn_size(pdata, plen), _libssh2_wincng_bn_size(gdata, glen)), _libssh2_wincng_bn_size(ydata, ylen)); offset = sizeof(BCRYPT_DSA_KEY_BLOB); keylen = offset + length * 3; if (xdata && xlen > 0) keylen += 20; key = malloc(keylen); if (!key) { return -1; } memset(key, 0, keylen); /* http://msdn.microsoft.com/library/windows/desktop/aa833126.aspx */ dsakey = (BCRYPT_DSA_KEY_BLOB *)key; dsakey->cbKey = length; memset(dsakey->Count, -1, sizeof(dsakey->Count)); memset(dsakey->Seed, -1, sizeof(dsakey->Seed)); if (qlen < 20) memcpy(dsakey->q + 20 - qlen, qdata, qlen); else memcpy(dsakey->q, qdata + qlen - 20, 20); if (plen < length) memcpy(key + offset + length - plen, pdata, plen); else memcpy(key + offset, pdata + plen - length, length); offset += length; if (glen < length) memcpy(key + offset + length - glen, gdata, glen); else memcpy(key + offset, gdata + glen - length, length); offset += length; if (ylen < length) memcpy(key + offset + length - ylen, ydata, ylen); else memcpy(key + offset, ydata + ylen - length, length); if (xdata && xlen > 0) { offset += length; if (xlen < 20) memcpy(key + offset + 20 - xlen, xdata, xlen); else memcpy(key + offset, xdata + xlen - 20, 20); lpszBlobType = BCRYPT_DSA_PRIVATE_BLOB; dsakey->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC; } else { lpszBlobType = BCRYPT_DSA_PUBLIC_BLOB; dsakey->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC; } ret = BCryptImportKeyPair(_libssh2_wincng.hAlgDSA, NULL, lpszBlobType, &hKey, key, keylen, 0); if (!BCRYPT_SUCCESS(ret)) { free(key); return -1; } *dsa = malloc(sizeof(libssh2_dsa_ctx)); if (!(*dsa)) { BCryptDestroyKey(hKey); free(key); return -1; } (*dsa)->hKey = hKey; (*dsa)->pbKeyObject = key; (*dsa)->cbKeyObject = keylen; return 0; }
int _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase) { #ifdef HAVE_LIBCRYPT32 BCRYPT_KEY_HANDLE hKey; unsigned char *pbEncoded, *pbStructInfo; unsigned long cbEncoded, cbStructInfo; int ret; (void)session; ret = _libssh2_wincng_load_private(session, filename, (const char *)passphrase, &pbEncoded, &cbEncoded); if (ret) { return -1; } ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, PKCS_RSA_PRIVATE_KEY, &pbStructInfo, &cbStructInfo); free(pbEncoded); if (ret) { return -1; } ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, LEGACY_RSAPRIVATE_BLOB, &hKey, pbStructInfo, cbStructInfo, 0); if (!BCRYPT_SUCCESS(ret)) { free(pbStructInfo); return -1; } *rsa = malloc(sizeof(libssh2_rsa_ctx)); if (!(*rsa)) { BCryptDestroyKey(hKey); free(pbStructInfo); return -1; } (*rsa)->hKey = hKey; (*rsa)->pbKeyObject = pbStructInfo; (*rsa)->cbKeyObject = cbStructInfo; return 0; #else (void)rsa; (void)filename; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to load RSA key from private key file: " "Method unsupported in Windows CNG backend"); #endif /* HAVE_LIBCRYPT32 */ }
int _libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen) { BCRYPT_KEY_HANDLE hKey; BCRYPT_RSAKEY_BLOB *rsakey; LPCWSTR lpszBlobType; unsigned char *key; unsigned long keylen, offset, mlen, p1len = 0, p2len = 0; int ret; mlen = max(_libssh2_wincng_bn_size(ndata, nlen), _libssh2_wincng_bn_size(ddata, dlen)); offset = sizeof(BCRYPT_RSAKEY_BLOB); keylen = offset + elen + mlen; if (ddata && dlen > 0) { p1len = max(_libssh2_wincng_bn_size(pdata, plen), _libssh2_wincng_bn_size(e1data, e1len)); p2len = max(_libssh2_wincng_bn_size(qdata, qlen), _libssh2_wincng_bn_size(e2data, e2len)); keylen += p1len * 3 + p2len * 2 + mlen; } key = malloc(keylen); if (!key) { return -1; } memset(key, 0, keylen); /* http://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ rsakey = (BCRYPT_RSAKEY_BLOB *)key; rsakey->BitLength = mlen * 8; rsakey->cbPublicExp = elen; rsakey->cbModulus = mlen; memcpy(key + offset, edata, elen); offset += elen; if (nlen < mlen) memcpy(key + offset + mlen - nlen, ndata, nlen); else memcpy(key + offset, ndata + nlen - mlen, mlen); if (ddata && dlen > 0) { offset += mlen; if (plen < p1len) memcpy(key + offset + p1len - plen, pdata, plen); else memcpy(key + offset, pdata + plen - p1len, p1len); offset += p1len; if (qlen < p2len) memcpy(key + offset + p2len - qlen, qdata, qlen); else memcpy(key + offset, qdata + qlen - p2len, p2len); offset += p2len; if (e1len < p1len) memcpy(key + offset + p1len - e1len, e1data, e1len); else memcpy(key + offset, e1data + e1len - p1len, p1len); offset += p1len; if (e2len < p2len) memcpy(key + offset + p2len - e2len, e2data, e2len); else memcpy(key + offset, e2data + e2len - p2len, p2len); offset += p2len; if (coefflen < p1len) memcpy(key + offset + p1len - coefflen, coeffdata, coefflen); else memcpy(key + offset, coeffdata + coefflen - p1len, p1len); offset += p1len; if (dlen < mlen) memcpy(key + offset + mlen - dlen, ddata, dlen); else memcpy(key + offset, ddata + dlen - mlen, mlen); lpszBlobType = BCRYPT_RSAFULLPRIVATE_BLOB; rsakey->Magic = BCRYPT_RSAFULLPRIVATE_MAGIC; rsakey->cbPrime1 = p1len; rsakey->cbPrime2 = p2len; } else { lpszBlobType = BCRYPT_RSAPUBLIC_BLOB; rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; rsakey->cbPrime1 = 0; rsakey->cbPrime2 = 0; } ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, lpszBlobType, &hKey, key, keylen, 0); if (!BCRYPT_SUCCESS(ret)) { free(key); return -1; } *rsa = malloc(sizeof(libssh2_rsa_ctx)); if (!(*rsa)) { BCryptDestroyKey(hKey); free(key); return -1; } (*rsa)->hKey = hKey; (*rsa)->pbKeyObject = key; (*rsa)->cbKeyObject = keylen; return 0; }
int _libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, unsigned long flags) { BCRYPT_PKCS1_PADDING_INFO paddingInfoPKCS1; void *pPaddingInfo; unsigned char *data, *hash; unsigned long datalen, hashlen; int ret; datalen = m_len; data = malloc(datalen); if (!data) { return -1; } hashlen = SHA_DIGEST_LENGTH; hash = malloc(hashlen); if (!hash) { free(data); return -1; } memcpy(data, m, datalen); ret = _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, hash, hashlen); free(data); if (ret) { free(hash); return -1; } datalen = sig_len; data = malloc(datalen); if (!data) { free(hash); return -1; } if (flags & BCRYPT_PAD_PKCS1) { paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM; pPaddingInfo = &paddingInfoPKCS1; } else pPaddingInfo = NULL; memcpy(data, sig, datalen); ret = BCryptVerifySignature(ctx->hKey, pPaddingInfo, hash, hashlen, data, datalen, flags); free(hash); free(data); return BCRYPT_SUCCESS(ret) ? 0 : -1; }
int _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), unsigned char *iv, unsigned char *secret, int encrypt) { BCRYPT_KEY_HANDLE hKey; BCRYPT_KEY_DATA_BLOB_HEADER *header; unsigned char *pbKeyObject, *pbIV, *key; unsigned long dwKeyObject, dwIV, dwBlockLength, cbData, keylen; int ret; (void)encrypt; ret = BCryptGetProperty(*type.phAlg, BCRYPT_OBJECT_LENGTH, (unsigned char *)&dwKeyObject, sizeof(dwKeyObject), &cbData, 0); if (!BCRYPT_SUCCESS(ret)) { return -1; } ret = BCryptGetProperty(*type.phAlg, BCRYPT_BLOCK_LENGTH, (unsigned char *)&dwBlockLength, sizeof(dwBlockLength), &cbData, 0); if (!BCRYPT_SUCCESS(ret)) { return -1; } pbKeyObject = malloc(dwKeyObject); if (!pbKeyObject) { return -1; } keylen = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + type.dwKeyLength; key = malloc(keylen); if (!key) { free(pbKeyObject); return -1; } header = (BCRYPT_KEY_DATA_BLOB_HEADER *)key; header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; header->cbKeyData = type.dwKeyLength; memcpy(key + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), secret, type.dwKeyLength); ret = BCryptImportKey(*type.phAlg, NULL, BCRYPT_KEY_DATA_BLOB, &hKey, pbKeyObject, dwKeyObject, key, keylen, 0); free(key); if (!BCRYPT_SUCCESS(ret)) { free(pbKeyObject); return -1; } if (type.dwUseIV) { pbIV = malloc(dwBlockLength); if (!pbIV) { BCryptDestroyKey(hKey); free(pbKeyObject); return -1; } dwIV = dwBlockLength; memcpy(pbIV, iv, dwIV); } else { pbIV = NULL; dwIV = 0; } ctx->hKey = hKey; ctx->pbKeyObject = pbKeyObject; ctx->pbIV = pbIV; ctx->dwKeyObject = dwKeyObject; ctx->dwIV = dwIV; ctx->dwBlockLength = dwBlockLength; return 0; }
int _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r, _libssh2_bn *a, _libssh2_bn *p, _libssh2_bn *m, _libssh2_bn_ctx *bnctx) { BCRYPT_KEY_HANDLE hKey; BCRYPT_RSAKEY_BLOB *rsakey; unsigned char *key, *bignum; unsigned long keylen, offset, length; int ret; (void)bnctx; if (!r || !a || !p || !m) return -1; offset = sizeof(BCRYPT_RSAKEY_BLOB); keylen = offset + p->length + m->length; key = malloc(keylen); if (!key) return -1; /* http://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ rsakey = (BCRYPT_RSAKEY_BLOB *)key; rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; rsakey->BitLength = m->length * 8; rsakey->cbPublicExp = p->length; rsakey->cbModulus = m->length; rsakey->cbPrime1 = 0; rsakey->cbPrime2 = 0; memcpy(key + offset, p->bignum, p->length); offset += p->length; memcpy(key + offset, m->bignum, m->length); ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, BCRYPT_RSAPUBLIC_BLOB, &hKey, key, keylen, BCRYPT_NO_KEY_VALIDATION); if (BCRYPT_SUCCESS(ret)) { ret = BCryptEncrypt(hKey, a->bignum, a->length, NULL, NULL, 0, NULL, 0, &length, BCRYPT_PAD_NONE); if (BCRYPT_SUCCESS(ret)) { if (!_libssh2_wincng_bignum_resize(r, length)) { length = max(a->length, length); bignum = malloc(length); if (bignum) { offset = length - a->length; memset(bignum, 0, offset); memcpy(bignum + offset, a->bignum, a->length); ret = BCryptEncrypt(hKey, bignum, length, NULL, NULL, 0, r->bignum, r->length, &offset, BCRYPT_PAD_NONE); free(bignum); if (BCRYPT_SUCCESS(ret)) { _libssh2_wincng_bignum_resize(r, offset); } } else ret = STATUS_NO_MEMORY; } else ret = STATUS_NO_MEMORY; } BCryptDestroyKey(hKey); } free(key); return BCRYPT_SUCCESS(ret) ? 0 : -1; }