Skip to content

Commit ed3bf7c

Browse files
author
John Bland
committed
use EVP_CIPHER_CTX_new to use malloc memory instead of a nodejs Buffer that gets written on top of
1 parent d200198 commit ed3bf7c

File tree

9 files changed

+164
-66
lines changed

9 files changed

+164
-66
lines changed

WolfSSLEVP.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var wolfcrypt = require('./build/Release/wolfcrypt');
2020
var stream = require('stream');
2121
var WolfSSLEVP = /** @class */ (function () {
2222
function WolfSSLEVP() {
23-
this.evp = Buffer.alloc(wolfcrypt.sizeof_EVP_CIPHER_CTX());
23+
this.evp = wolfcrypt.EVP_CIPHER_CTX_new();
2424
this.totalInputLength = 0;
2525
}
2626
/**
@@ -64,6 +64,7 @@ var WolfSSLEVP = /** @class */ (function () {
6464
var outBuffer = Buffer.alloc(this.totalInputLength);
6565
this.totalInputLength = 0;
6666
var ret = wolfcrypt.EVP_CipherFinal(this.evp, outBuffer);
67+
wolfcrypt.EVP_CIPHER_CTX_free(this.evp);
6768
if (ret < 0) {
6869
throw 'Failed to finalize cipher';
6970
}

WolfSSLEVP.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ const wolfcrypt = require( './build/Release/wolfcrypt' );
22
const stream = require( 'stream' );
33

44
class WolfSSLEVP {
5-
protected evp: Buffer
5+
protected evp: number
66
protected totalInputLength: number
77

88
public constructor() {
9-
this.evp = Buffer.alloc( wolfcrypt.sizeof_EVP_CIPHER_CTX() )
9+
this.evp = wolfcrypt.EVP_CIPHER_CTX_new()
1010
this.totalInputLength = 0
1111
}
1212

@@ -63,6 +63,7 @@ class WolfSSLEVP {
6363
this.totalInputLength = 0;
6464

6565
let ret = wolfcrypt.EVP_CipherFinal( this.evp, outBuffer )
66+
wolfcrypt.EVP_CIPHER_CTX_free( this.evp )
6667

6768
if ( ret < 0 )
6869
{

binding.gyp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"cflags!": [ "-fno-exceptions" ],
55
"cflags_cc!": [ "-fno-exceptions" ],
66
"sources": [
7-
"wolfbind/main.cpp"
7+
"wolfbind/main.cpp",
8+
"wolfbind/evp.cpp"
89
],
910
'include_dirs': [
1011
"<!@(node -p \"require('node-addon-api').include\")"

main.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ if (actual == expected) {
2929
else {
3030
console.log('FAIL plaintext does not match what we expected', expected, expected.length, actual, actual.length);
3131
}
32+
// finalize frees the evp context, need to make it again
33+
decrypt = new WolfSSLEVP_1.WolfSSLDecryptor('AES-256-CBC', key, iv);
34+
encrypt = new WolfSSLEVP_1.WolfSSLEncryptor('AES-256-CBC', key, iv);
3235
var parts = [];
3336
var i;
3437
// lets put the api through its paces

main.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { WolfSSLEncryptor, WolfSSLDecryptor, WolfSSLEncryptionStream, WolfSSLDec
22

33
const key = Buffer.from('12345678901234567890123456789012')
44
const iv = Buffer.from('1234567890123456')
5-
const decrypt = new WolfSSLDecryptor('AES-256-CBC', key, iv)
6-
const encrypt = new WolfSSLEncryptor('AES-256-CBC', key, iv)
5+
let decrypt = new WolfSSLDecryptor('AES-256-CBC', key, iv)
6+
let encrypt = new WolfSSLEncryptor('AES-256-CBC', key, iv)
77
const expected = 'test'
88
const expectedCiphertext = '24d31b1e41fc8c40e521531d67c72c20'
99
// 17 bytes to test padding
@@ -37,6 +37,10 @@ else
3737
console.log( 'FAIL plaintext does not match what we expected', expected, expected.length, actual, actual.length )
3838
}
3939

40+
// finalize frees the evp context, need to make it again
41+
decrypt = new WolfSSLDecryptor('AES-256-CBC', key, iv)
42+
encrypt = new WolfSSLEncryptor('AES-256-CBC', key, iv)
43+
4044
let parts = []
4145
let i;
4246

wolfbind/evp.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include "./h/evp.h"
2+
3+
Napi::Number sizeof_EVP_CIPHER_CTX(const Napi::CallbackInfo& info)
4+
{
5+
Napi::Env env = info.Env();
6+
7+
return Napi::Number::New( env, sizeof( EVP_CIPHER_CTX ) );
8+
}
9+
10+
Napi::Value bind_EVP_CIPHER_CTX_new(const Napi::CallbackInfo& info)
11+
{
12+
Napi::Env env = info.Env();
13+
EVP_CIPHER_CTX* evp = EVP_CIPHER_CTX_new();
14+
Napi::External<EVP_CIPHER_CTX> evp_ext = Napi::External<EVP_CIPHER_CTX>::New( env, evp );
15+
16+
return evp_ext;
17+
}
18+
19+
Napi::Number bind_EVP_CipherInit(const Napi::CallbackInfo& info)
20+
{
21+
Napi::Env env = info.Env();
22+
int ret;
23+
EVP_CIPHER_CTX* evp = info[0].As<Napi::External<EVP_CIPHER_CTX>>().Data();
24+
std::string type = info[1].As<Napi::String>().Utf8Value();
25+
uint8_t* key = info[2].As<Napi::Uint8Array>().Data();
26+
uint8_t* iv = info[3].As<Napi::Uint8Array>().Data();
27+
int enc = info[4].As<Napi::Number>().Int32Value();
28+
29+
ret = EVP_CipherInit( evp, type.c_str(), key, iv, enc );
30+
31+
return Napi::Number::New( env, ret );
32+
}
33+
34+
Napi::Number bind_EVP_CipherUpdate(const Napi::CallbackInfo& info)
35+
{
36+
Napi::Env env = info.Env();
37+
int ret;
38+
EVP_CIPHER_CTX* evp = info[0].As<Napi::External<EVP_CIPHER_CTX>>().Data();
39+
uint8_t* out_buf = info[1].As<Napi::Uint8Array>().Data();
40+
int out_len;
41+
uint8_t* in_buf = info[2].As<Napi::Uint8Array>().Data();
42+
int in_len = info[3].As<Napi::Number>().Int32Value();
43+
44+
ret = EVP_CipherUpdate( evp, out_buf, &out_len, in_buf, in_len );
45+
46+
if ( ret != WOLFSSL_SUCCESS )
47+
out_len = -1;
48+
49+
return Napi::Number::New( env, out_len );
50+
}
51+
52+
Napi::Number bind_EVP_CipherFinal(const Napi::CallbackInfo& info)
53+
{
54+
Napi::Env env = info.Env();
55+
int ret;
56+
EVP_CIPHER_CTX* evp = info[0].As<Napi::External<EVP_CIPHER_CTX>>().Data();
57+
uint8_t* out_buf = info[1].As<Napi::Uint8Array>().Data();
58+
int out_len;
59+
60+
ret = EVP_CipherFinal( evp, out_buf, &out_len );
61+
62+
if ( ret != WOLFSSL_SUCCESS )
63+
out_len = -1;
64+
65+
return Napi::Number::New( env, out_len );
66+
}
67+
68+
void bind_EVP_CIPHER_CTX_free(const Napi::CallbackInfo& info)
69+
{
70+
EVP_CIPHER_CTX* evp = info[0].As<Napi::External<EVP_CIPHER_CTX>>().Data();
71+
72+
EVP_CIPHER_CTX_free( evp );
73+
}

wolfbind/h/evp.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <napi.h>
2+
#include <stdio.h>
3+
#include <cstring>
4+
#include "wolfssl/options.h"
5+
#include "wolfssl/ssl.h"
6+
#include <wolfssl/wolfcrypt/settings.h>
7+
#include <wolfssl/openssl/evp.h>
8+
9+
Napi::Value bind_EVP_CIPHER_CTX_new(const Napi::CallbackInfo& info);
10+
Napi::Number bind_EVP_CipherInit(const Napi::CallbackInfo& info);
11+
Napi::Number bind_EVP_CipherUpdate(const Napi::CallbackInfo& info);
12+
Napi::Number bind_EVP_CipherFinal(const Napi::CallbackInfo& info);
13+
void bind_EVP_CIPHER_CTX_free(const Napi::CallbackInfo& info);

wolfbind/hmac.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "./h/hmac.h"
2+
3+
Napi::Number sizeof_EVP_CIPHER_CTX(const Napi::CallbackInfo& info)
4+
{
5+
Napi::Env env = info.Env();
6+
7+
return Napi::Number::New( env, sizeof( Hmac ) );
8+
}
9+
10+
Napi::Number bind_wc_HmacSetKey(const Napi::CallbackInfo& info)
11+
{
12+
Napi::Env env = info.Env();
13+
int ret;
14+
Hmac* hmac = (Hmac*)( info[0].As<Napi::Uint8Array>().Data() );
15+
int type = info[1].As<Napi::Number>().Int32Value();
16+
uint8_t* key = info[2].As<Napi::Uint8Array>().Data();
17+
uint32_t keySz = info[3].As<Napi::Number>().Uint32Value();
18+
19+
ret = wc_HmacSetKey( hmac, type, key, keySz );
20+
21+
return Napi::Number::New( env, ret );
22+
}
23+
24+
Napi::Number bind_wc_HmacUpdate(const Napi::CallbackInfo& info)
25+
{
26+
Napi::Env env = info.Env();
27+
int ret;
28+
Hmac* hmac = (Hmac*)( info[0].As<Napi::Uint8Array>().Data() );
29+
uint8_t* in = info[1].As<Napi::Uint8Array>().Data();
30+
int inSz = info[2].As<Napi::Number>().Int32Value();
31+
32+
ret = wc_HmacUpdate( hmac, in, inSz );
33+
34+
return Napi::Number::New( env, ret );
35+
}
36+
37+
Napi::Number bind_wc_HmacFinal(const Napi::CallbackInfo& info)
38+
{
39+
Napi::Env env = info.Env();
40+
int ret;
41+
Hmac* hmac = (Hmac*)( info[0].As<Napi::Uint8Array>().Data() );
42+
uint8_t* out = info[1].As<Napi::Uint8Array>().Data();
43+
44+
ret = wc_HmacFinal( hmac, out );
45+
46+
return Napi::Number::New( env, ret );
47+
}
48+
49+
Napi::Number bind_wc_HmacFree(const Napi::CallbackInfo& info)
50+
{
51+
Napi::Env env = info.Env();
52+
int ret;
53+
Hmac* hmac = (Hmac*)( info[0].As<Napi::Uint8Array>().Data() );
54+
55+
ret = wc_HmacFree( hmac );
56+
57+
return Napi::Number::New( env, ret );
58+
}

wolfbind/main.cpp

Lines changed: 4 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
#include <napi.h>
22
#include <stdio.h>
33
#include <cstring>
4-
#include "wolfssl/options.h"
5-
#include "wolfssl/ssl.h"
4+
#include "./h/evp.h"
5+
#include <wolfssl/options.h>
66
#include <wolfssl/wolfcrypt/settings.h>
77
#include <wolfssl/wolfcrypt/aes.h>
8-
#include <wolfssl/openssl/evp.h>
98

109
using namespace Napi;
1110

@@ -16,62 +15,6 @@ typedef struct WrappedKey
1615
uint8_t iv[16];
1716
} WrappedKey;
1817

19-
Napi::Number sizeof_EVP_CIPHER_CTX(const Napi::CallbackInfo& info)
20-
{
21-
Napi::Env env = info.Env();
22-
23-
return Napi::Number::New( env, sizeof( EVP_CIPHER_CTX ) );
24-
}
25-
26-
Napi::Number bind_EVP_CipherInit(const Napi::CallbackInfo& info)
27-
{
28-
Napi::Env env = info.Env();
29-
int ret;
30-
EVP_CIPHER_CTX* evp = (EVP_CIPHER_CTX*)( info[0].As<Napi::Uint8Array>().Data() );
31-
std::string type = info[1].As<Napi::String>().Utf8Value();
32-
uint8_t* key = info[2].As<Napi::Uint8Array>().Data();
33-
uint8_t* iv = info[3].As<Napi::Uint8Array>().Data();
34-
int enc = info[4].As<Napi::Number>().Int32Value();
35-
36-
ret = EVP_CipherInit( evp, type.c_str(), key, iv, enc );
37-
38-
return Napi::Number::New( env, ret );
39-
}
40-
41-
Napi::Number bind_EVP_CipherUpdate(const Napi::CallbackInfo& info)
42-
{
43-
Napi::Env env = info.Env();
44-
int ret;
45-
EVP_CIPHER_CTX* evp = (EVP_CIPHER_CTX*)( info[0].As<Napi::Uint8Array>().Data() );
46-
uint8_t* out_buf = info[1].As<Napi::Uint8Array>().Data();
47-
int out_len;
48-
uint8_t* in_buf = info[2].As<Napi::Uint8Array>().Data();
49-
int in_len = info[3].As<Napi::Number>().Int32Value();
50-
51-
ret = EVP_CipherUpdate( evp, out_buf, &out_len, in_buf, in_len );
52-
53-
if ( ret != WOLFSSL_SUCCESS )
54-
out_len = -1;
55-
56-
return Napi::Number::New( env, out_len );
57-
}
58-
59-
Napi::Number bind_EVP_CipherFinal(const Napi::CallbackInfo& info)
60-
{
61-
Napi::Env env = info.Env();
62-
int ret;
63-
EVP_CIPHER_CTX* evp = (EVP_CIPHER_CTX*)( info[0].As<Napi::Uint8Array>().Data() );
64-
uint8_t* out_buf = info[1].As<Napi::Uint8Array>().Data();
65-
int out_len;
66-
67-
ret = EVP_CipherFinal( evp, out_buf, &out_len );
68-
69-
if ( ret != WOLFSSL_SUCCESS )
70-
out_len = -1;
71-
72-
return Napi::Number::New( env, out_len );
73-
}
74-
7518
Napi::Number MakeAes(const Napi::CallbackInfo& info)
7619
{
7720
int ret = 0;
@@ -135,10 +78,11 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
13578
exports.Set(Napi::String::New(env, "Encrypt"), Napi::Function::New(env, Encrypt));
13679
exports.Set(Napi::String::New(env, "Decrypt"), Napi::Function::New(env, Decrypt));
13780

138-
exports.Set(Napi::String::New(env, "sizeof_EVP_CIPHER_CTX"), Napi::Function::New(env, sizeof_EVP_CIPHER_CTX));
81+
exports.Set(Napi::String::New(env, "EVP_CIPHER_CTX_new"), Napi::Function::New(env, bind_EVP_CIPHER_CTX_new));
13982
exports.Set(Napi::String::New(env, "EVP_CipherInit"), Napi::Function::New(env, bind_EVP_CipherInit));
14083
exports.Set(Napi::String::New(env, "EVP_CipherUpdate"), Napi::Function::New(env, bind_EVP_CipherUpdate));
14184
exports.Set(Napi::String::New(env, "EVP_CipherFinal"), Napi::Function::New(env, bind_EVP_CipherFinal));
85+
exports.Set(Napi::String::New(env, "EVP_CIPHER_CTX_free"), Napi::Function::New(env, bind_EVP_CIPHER_CTX_free));
14286

14387
return exports;
14488
}

0 commit comments

Comments
 (0)