Updated RC4 API, fixed crashing bug.
authorArmin Novak <armin.novak@gmail.com>
Sun, 28 Feb 2016 10:12:17 +0000 (11:12 +0100)
committerArmin Novak <armin.novak@gmail.com>
Sun, 28 Feb 2016 10:19:29 +0000 (11:19 +0100)
libfreerdp/core/connection.c
libfreerdp/core/license.c
libfreerdp/core/rdp.c
libfreerdp/core/security.c
winpr/include/winpr/crypto.h
winpr/libwinpr/crypto/cipher.c
winpr/libwinpr/crypto/test/TestCryptoCipher.c
winpr/libwinpr/sspi/NTLM/ntlm.c
winpr/libwinpr/sspi/NTLM/ntlm.h
winpr/libwinpr/sspi/NTLM/ntlm_compute.c

index 496e858..c23b421 100644 (file)
@@ -513,12 +513,27 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
                goto end;
        }
 
-       winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len);
-       winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len);
+       if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
+               goto end;
+       if (!winpr_RC4_New(&rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
+               goto end;
 
        ret = TRUE;
 end:
        free(crypt_client_random);
+       if (!ret)
+       {
+               winpr_Cipher_Free(rdp->fips_decrypt);
+               winpr_Cipher_Free(rdp->fips_encrypt);
+               winpr_RC4_Free(rdp->rc4_decrypt_key);
+               winpr_RC4_Free(rdp->rc4_encrypt_key);
+
+               rdp->fips_decrypt = NULL;
+               rdp->fips_encrypt = NULL;
+               rdp->rc4_decrypt_key = NULL;
+               rdp->rc4_encrypt_key = NULL;
+       }
+
        return ret;
 }
 
@@ -575,12 +590,12 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
        if (rand_len != key_len + 8)
        {
                WLog_ERR(TAG, "invalid encrypted client random length");
-               goto end2;
+               goto end;
        }
 
        crypt_client_random = calloc(1, rand_len);
        if (!crypt_client_random)
-               goto end2;
+               goto end;
        Stream_Read(s, crypt_client_random, rand_len);
 
        mod = rdp->settings->RdpServerRsaKey->Modulus;
@@ -589,9 +604,7 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
 
        /* now calculate encrypt / decrypt and update keys */
        if (!security_establish_keys(client_random, rdp))
-       {
                goto end;
-       }
 
        rdp->do_crypt = TRUE;
 
@@ -621,15 +634,28 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
                goto end;
        }
 
-       winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len);
-       winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len);
+       if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
+               goto end;
+       if (!winpr_RC4_New(&rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
+               goto end;
 
        ret = TRUE;
 end:
        free(crypt_client_random);
-end2:
        free(client_random);
 
+       if (!ret)
+       {
+               winpr_Cipher_Free(rdp->fips_encrypt);
+               winpr_Cipher_Free(rdp->fips_decrypt);
+               winpr_RC4_Free(rdp->rc4_encrypt_key);
+               winpr_RC4_Free(rdp->rc4_decrypt_key);
+
+               rdp->fips_encrypt = NULL;
+               rdp->fips_decrypt = NULL;
+               rdp->rc4_encrypt_key = NULL;
+               rdp->rc4_decrypt_key = NULL;
+       }
        return ret;
 }
 
index 4852f9b..cc3e64a 100644 (file)
@@ -458,20 +458,22 @@ BOOL license_encrypt_premaster_secret(rdpLicense* license)
 
 BOOL license_decrypt_platform_challenge(rdpLicense* license)
 {
-       WINPR_RC4_CTX rc4;
+       BOOL rc;
+       WINPR_RC4_CTX* rc4;
 
        license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length);
        if (!license->PlatformChallenge->data)
                return FALSE;
        license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
 
-       winpr_RC4_Init(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
-       winpr_RC4_Update(&rc4, license->EncryptedPlatformChallenge->length,
+       if (!winpr_RC4_New(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH))
+               return FALSE;
+       rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
                           license->EncryptedPlatformChallenge->data,
                           license->PlatformChallenge->data);
 
-       winpr_RC4_Final(&rc4);
-       return TRUE;
+       winpr_RC4_Free(rc4);
+       return rc;
 }
 
 /**
@@ -1015,7 +1017,7 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
        wStream* s;
        int length;
        BYTE* buffer;
-       WINPR_RC4_CTX rc4;
+       WINPR_RC4_CTX* rc4;
        BYTE mac_data[16];
        BOOL status;
 
@@ -1036,14 +1038,20 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
        if (!status)
                return FALSE;
 
-       winpr_RC4_Init(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
+       if (!winpr_RC4_New(&rc4, license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH))
+               return FALSE;
 
        buffer = (BYTE*) malloc(HWID_LENGTH);
        if (!buffer)
                return FALSE;
 
-       winpr_RC4_Update(&rc4, HWID_LENGTH, license->HardwareId, buffer);
-       winpr_RC4_Final(&rc4);
+       status = winpr_RC4_Update(rc4, HWID_LENGTH, license->HardwareId, buffer);
+       winpr_RC4_Free(rc4);
+       if (!status)
+       {
+               free(buffer);
+               return FALSE;
+       }
 
        license->EncryptedHardwareId->type = BB_DATA_BLOB;
        license->EncryptedHardwareId->data = buffer;
index 026091a..61a44dc 100644 (file)
@@ -1590,13 +1590,13 @@ void rdp_reset(rdpRdp* rdp)
 
        if (rdp->rc4_decrypt_key)
        {
-               winpr_RC4_Final(rdp->rc4_decrypt_key);
+               winpr_RC4_Free(rdp->rc4_decrypt_key);
                rdp->rc4_decrypt_key = NULL;
        }
 
        if (rdp->rc4_encrypt_key)
        {
-               winpr_RC4_Final(rdp->rc4_encrypt_key);
+               winpr_RC4_Free(rdp->rc4_encrypt_key);
                rdp->rc4_encrypt_key = NULL;
        }
 
@@ -1661,8 +1661,8 @@ void rdp_free(rdpRdp* rdp)
 {
        if (rdp)
        {
-               winpr_RC4_Final(rdp->rc4_decrypt_key);
-               winpr_RC4_Final(rdp->rc4_encrypt_key);
+               winpr_RC4_Free(rdp->rc4_decrypt_key);
+               winpr_RC4_Free(rdp->rc4_encrypt_key);
                winpr_Cipher_Free(rdp->fips_encrypt);
                winpr_Cipher_Free(rdp->fips_decrypt);
                free(rdp->fips_hmac);
index 0d67c8a..4158093 100644 (file)
@@ -538,7 +538,8 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
        BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH];
        WINPR_MD5_CTX md5;
        WINPR_SHA1_CTX sha1;
-       WINPR_RC4_CTX rc4;
+       WINPR_RC4_CTX* rc4;
+       BOOL rc;
        BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
 
        if (!winpr_SHA1_Init(&sha1))
@@ -563,11 +564,12 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
        if (!winpr_MD5_Final(&md5, key, WINPR_MD5_DIGEST_LENGTH))
                return FALSE;
 
-       if (!winpr_RC4_Init(&rc4, key, key_len))
+       if (!winpr_RC4_New(&rc4, key, key_len))
                return FALSE;
-       if (!winpr_RC4_Update(&rc4, key_len, key, key))
-               return FALSE;
-       if (!winpr_RC4_Final(&rc4))
+       rc = winpr_RC4_Update(rc4, key_len, key, key);
+       winpr_RC4_Free(rc4);
+
+       if (!rc)
                return FALSE;
 
        if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
@@ -585,9 +587,8 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
                if (!security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, rdp))
                        return FALSE;
 
-               if (!winpr_RC4_Final(rdp->rc4_encrypt_key))
-                       return FALSE;
-               if (!winpr_RC4_Init(rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
+               winpr_RC4_Free(rdp->rc4_encrypt_key);
+               if (!winpr_RC4_New(&rdp->rc4_encrypt_key, rdp->encrypt_key, rdp->rc4_key_len))
                        return FALSE;
 
                rdp->encrypt_use_count = 0;
@@ -609,9 +610,8 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
        {
                if (!security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, rdp))
                        return FALSE;
-               if (!winpr_RC4_Final(rdp->rc4_decrypt_key))
-                       return FALSE;
-               if (!winpr_RC4_Init(rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
+               winpr_RC4_Free(rdp->rc4_decrypt_key);
+               if (!winpr_RC4_New(&rdp->rc4_decrypt_key, rdp->decrypt_key, rdp->rc4_key_len))
                        return FALSE;
 
                rdp->decrypt_use_count = 0;
index b831da8..0808582 100644 (file)
@@ -901,9 +901,9 @@ typedef union _WINPR_RC4_CTX WINPR_RC4_CTX;
 extern "C" {
 #endif
 
-WINPR_API BOOL winpr_RC4_Init(WINPR_RC4_CTX* ctx, const BYTE* key, size_t keylen);
+WINPR_API BOOL winpr_RC4_New(WINPR_RC4_CTX** ctx, const BYTE* key, size_t keylen);
 WINPR_API BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output);
-WINPR_API BOOL winpr_RC4_Final(WINPR_RC4_CTX* ctx);
+WINPR_API void winpr_RC4_Free(WINPR_RC4_CTX* ctx);
 
 #ifdef __cplusplus
 }
index b8eb9d6..5c571b1 100644 (file)
  * RC4
  */
 
-BOOL winpr_RC4_Init(WINPR_RC4_CTX* ctx, const BYTE* key, size_t keylen)
+BOOL winpr_RC4_New(WINPR_RC4_CTX** octx, const BYTE* key, size_t keylen)
 {
+       WINPR_RC4_CTX* ctx = NULL;
+
+       if (!octx || !key || (keylen == 0))
+               return FALSE;
+
+       ctx = calloc(1, sizeof(WINPR_RC4_CTX));
+       if (!ctx)
+               return FALSE;
+
 #if defined(WITH_OPENSSL)
        RC4_set_key((RC4_KEY*) ctx, keylen, key);
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
        mbedtls_arc4_init((mbedtls_arc4_context*) ctx);
        mbedtls_arc4_setup((mbedtls_arc4_context*) ctx, key, keylen);
 #endif
-    return TRUE;
+       *octx = ctx;
+
+       return TRUE;
 }
 
 BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE* output)
@@ -60,20 +71,23 @@ BOOL winpr_RC4_Update(WINPR_RC4_CTX* ctx, size_t length, const BYTE* input, BYTE
        RC4((RC4_KEY*) ctx, length, input, output);
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
        if (mbedtls_arc4_crypt((mbedtls_arc4_context*) ctx, length, input, output) != 0)
-        return FALSE;
+               return FALSE;
 #endif
 
-    return TRUE;
+       return TRUE;
 }
 
-BOOL winpr_RC4_Final(WINPR_RC4_CTX* ctx)
+void winpr_RC4_Free(WINPR_RC4_CTX* ctx)
 {
+       if (!ctx)
+               return;
+
 #if defined(WITH_OPENSSL)
 
 #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C)
        mbedtls_arc4_free((mbedtls_arc4_context*) ctx);
 #endif
-    return TRUE;
+       free(ctx);
 }
 
 /**
@@ -502,7 +516,7 @@ mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher)
 
 BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** cctx, int cipher, int op, const BYTE* key, const BYTE* iv)
 {
-    WINPR_CIPHER_CTX* ctx;
+       WINPR_CIPHER_CTX* ctx;
 #if defined(WITH_OPENSSL)
        int operation;
        const EVP_CIPHER* evp;
@@ -514,10 +528,10 @@ BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** cctx, int cipher, int op, const BYTE* k
        const mbedtls_cipher_info_t* cipher_info;
 #endif
 
-    ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
-    if (!ctx)
-        return FALSE;
-    
+       ctx = calloc(1, sizeof(WINPR_CIPHER_CTX));
+       if (!ctx)
+               return FALSE;
+       
 #if defined(WITH_OPENSSL)
        octx = (EVP_CIPHER_CTX*)ctx;
        evp = winpr_openssl_get_evp_cipher(cipher);
@@ -551,7 +565,7 @@ BOOL winpr_Cipher_New(WINPR_CIPHER_CTX** cctx, int cipher, int op, const BYTE* k
                return FALSE;
 #endif
 
-    *cctx = ctx;
+       *cctx = ctx;
        return TRUE;
 }
 
@@ -589,8 +603,8 @@ BOOL winpr_Cipher_Final(WINPR_CIPHER_CTX* ctx, BYTE* output, size_t* olen)
 
 void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx)
 {
-    if (!ctx)
-        return;
+       if (!ctx)
+               return;
 
 #if defined(WITH_OPENSSL)
        EVP_CIPHER_CTX_cleanup((EVP_CIPHER_CTX*) ctx);
index 29aa925..98ceb8f 100644 (file)
@@ -7,22 +7,26 @@ static const BYTE* TEST_RC4_KEY = (BYTE*) "Key";
 static const char* TEST_RC4_PLAINTEXT = "Plaintext";
 static const BYTE* TEST_RC4_CIPHERTEXT = (BYTE*) "\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3";
 
-BOOL test_crypto_cipher_rc4()
+static BOOL test_crypto_cipher_rc4()
 {
        size_t len;
-       BYTE* text;
-       WINPR_RC4_CTX ctx;
+       BOOL rc = FALSE;
+       BYTE* text = NULL;
+       WINPR_RC4_CTX* ctx;
 
        len = strlen(TEST_RC4_PLAINTEXT);
 
        text = (BYTE*) calloc(1, len);
 
        if (!text)
-               return FALSE;
+               goto out;
 
-       winpr_RC4_Init(&ctx, TEST_RC4_KEY, strlen((char*) TEST_RC4_KEY));
-       winpr_RC4_Update(&ctx, len, (BYTE*) TEST_RC4_PLAINTEXT, text);
-       winpr_RC4_Final(&ctx);
+       if (!winpr_RC4_New(&ctx, TEST_RC4_KEY, strlen((char*) TEST_RC4_KEY)))
+               goto out;
+       rc = winpr_RC4_Update(ctx, len, (BYTE*) TEST_RC4_PLAINTEXT, text);
+       winpr_RC4_Free(ctx);
+       if (!rc)
+               goto out;
 
        if (memcmp(text, TEST_RC4_CIPHERTEXT, len) != 0)
        {
@@ -36,11 +40,14 @@ BOOL test_crypto_cipher_rc4()
 
                free(actual);
                free(expected);
-
-               return FALSE;
+               goto out;
        }
 
-       return TRUE;
+       rc = TRUE;
+
+out:
+       free(text);
+       return rc;
 }
 
 static const BYTE* TEST_RAND_DATA = (BYTE*)
@@ -56,7 +63,7 @@ static const BYTE* TEST_CIPHER_KEY = (BYTE*)
 static const BYTE* TEST_CIPHER_IV = (BYTE*)
        "\xFE\xE3\x9F\xF0\xD1\x5E\x37\x0C\xAB\xAB\x9B\x04\xF3\xDB\x99\x15";
 
-BOOL test_crypto_cipher_key()
+static BOOL test_crypto_cipher_key()
 {
        int status;
        BYTE key[32];
index 99d63dd..0602466 100644 (file)
@@ -239,6 +239,8 @@ void ntlm_ContextFree(NTLM_CONTEXT* context)
        if (!context)
                return;
 
+       winpr_RC4_Free(context->SendRc4Seal);
+       winpr_RC4_Free(context->RecvRc4Seal);
        sspi_SecBufferFree(&context->NegotiateMessage);
        sspi_SecBufferFree(&context->ChallengeMessage);
        sspi_SecBufferFree(&context->AuthenticateMessage);
@@ -931,7 +933,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
        /* Encrypt message using with RC4, result overwrites original buffer */
 
        if (context->confidentiality)
-               winpr_RC4_Update(&context->SendRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
+               winpr_RC4_Update(context->SendRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
        else
                CopyMemory(data_buffer->pvBuffer, data, length);
 
@@ -943,7 +945,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
 #endif
        free(data);
        /* RC4-encrypt first 8 bytes of digest */
-       winpr_RC4_Update(&context->SendRc4Seal, 8, digest, checksum);
+       winpr_RC4_Update(context->SendRc4Seal, 8, digest, checksum);
        signature = (BYTE*) signature_buffer->pvBuffer;
        /* Concatenate version, ciphertext and sequence number to build signature */
        CopyMemory(signature, (void*) &version, 4);
@@ -1000,7 +1002,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD
        /* Decrypt message using with RC4, result overwrites original buffer */
 
        if (context->confidentiality)
-               winpr_RC4_Update(&context->RecvRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
+               winpr_RC4_Update(context->RecvRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
        else
                CopyMemory(data_buffer->pvBuffer, data, length);
 
@@ -1017,7 +1019,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD
 #endif
        free(data);
        /* RC4-encrypt first 8 bytes of digest */
-       winpr_RC4_Update(&context->RecvRc4Seal, 8, digest, checksum);
+       winpr_RC4_Update(context->RecvRc4Seal, 8, digest, checksum);
        /* Concatenate version, ciphertext and sequence number to build signature */
        CopyMemory(expected_signature, (void*) &version, 4);
        CopyMemory(&expected_signature[4], (void*) checksum, 8);
index bdccecd..8253f3d 100644 (file)
@@ -225,8 +225,8 @@ struct _NTLM_CONTEXT
        BYTE MachineID[32];
        BOOL SendVersionInfo;
        BOOL confidentiality;
-       WINPR_RC4_CTX SendRc4Seal;
-       WINPR_RC4_CTX RecvRc4Seal;
+       WINPR_RC4_CTX* SendRc4Seal;
+       WINPR_RC4_CTX* RecvRc4Seal;
        BYTE* SendSigningKey;
        BYTE* RecvSigningKey;
        BYTE* SendSealingKey;
index b341dbc..092f250 100644 (file)
@@ -341,8 +341,8 @@ int ntlm_compute_lm_v2_response(NTLM_CONTEXT* context)
        response = (BYTE*) context->LmChallengeResponse.pvBuffer;
        /* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */
        winpr_HMAC(WINPR_MD_MD5, (void*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
-            (BYTE*) value, WINPR_MD5_DIGEST_LENGTH,
-            (BYTE*) response, WINPR_MD5_DIGEST_LENGTH);
+                       (BYTE*) value, WINPR_MD5_DIGEST_LENGTH,
+                       (BYTE*) response, WINPR_MD5_DIGEST_LENGTH);
        /* Concatenate the resulting HMAC-MD5 hash and the client challenge, giving us the LMv2 response (24 bytes) */
        CopyMemory(&response[16], context->ClientChallenge, 8);
        return 1;
@@ -412,8 +412,8 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
        CopyMemory(blob, context->ServerChallenge, 8);
        CopyMemory(&blob[8], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
        winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
-            (BYTE*) ntlm_v2_temp_chal.pvBuffer, ntlm_v2_temp_chal.cbBuffer,
-            (BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH);
+                       (BYTE*) ntlm_v2_temp_chal.pvBuffer, ntlm_v2_temp_chal.cbBuffer,
+                       (BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH);
 
        /* NtChallengeResponse, Concatenate NTProofStr with temp */
 
@@ -425,8 +425,8 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
        CopyMemory(&blob[16], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
        /* Compute SessionBaseKey, the HMAC-MD5 hash of NTProofStr using the NTLMv2 hash as the key */
        winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, WINPR_MD5_DIGEST_LENGTH,
-            (BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH,
-            (BYTE*) context->SessionBaseKey, WINPR_MD5_DIGEST_LENGTH);
+                       (BYTE*) nt_proof_str, WINPR_MD5_DIGEST_LENGTH,
+                       (BYTE*) context->SessionBaseKey, WINPR_MD5_DIGEST_LENGTH);
        sspi_SecBufferFree(&ntlm_v2_temp);
        sspi_SecBufferFree(&ntlm_v2_temp_chal);
        return 1;
@@ -442,10 +442,12 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
 
 void ntlm_rc4k(BYTE* key, int length, BYTE* plaintext, BYTE* ciphertext)
 {
-       WINPR_RC4_CTX rc4;
-       winpr_RC4_Init(&rc4, (void*) key, 16);
-       winpr_RC4_Update(&rc4, length, (void*) plaintext, (void*) ciphertext);
-       winpr_RC4_Final(&rc4);
+       WINPR_RC4_CTX* rc4;
+       if (winpr_RC4_New(&rc4, (void*) key, 16))
+       {
+               winpr_RC4_Update(rc4, length, (void*) plaintext, (void*) ciphertext);
+               winpr_RC4_Free(rc4);
+       }
 }
 
 /**
@@ -662,8 +664,8 @@ void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context)
                context->RecvSigningKey = context->ClientSigningKey;
                context->SendSealingKey = context->ClientSealingKey;
                context->RecvSealingKey = context->ServerSealingKey;
-               winpr_RC4_Init(&context->SendRc4Seal, context->ServerSealingKey, 16);
-               winpr_RC4_Init(&context->RecvRc4Seal, context->ClientSealingKey, 16);
+               winpr_RC4_New(&context->SendRc4Seal, context->ServerSealingKey, 16);
+               winpr_RC4_New(&context->RecvRc4Seal, context->ClientSealingKey, 16);
        }
        else
        {
@@ -671,8 +673,8 @@ void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context)
                context->RecvSigningKey = context->ServerSigningKey;
                context->SendSealingKey = context->ServerSealingKey;
                context->RecvSealingKey = context->ClientSealingKey;
-               winpr_RC4_Init(&context->SendRc4Seal, context->ClientSealingKey, 16);
-               winpr_RC4_Init(&context->RecvRc4Seal, context->ServerSealingKey, 16);
+               winpr_RC4_New(&context->SendRc4Seal, context->ClientSealingKey, 16);
+               winpr_RC4_New(&context->RecvRc4Seal, context->ServerSealingKey, 16);
        }
 }