@@ -3807,8 +3807,17 @@ void CipherBase::InitIv(const char* cipher_type,
3807
3807
const int expected_iv_len = EVP_CIPHER_iv_length (cipher);
3808
3808
const int mode = EVP_CIPHER_mode (cipher);
3809
3809
const bool is_gcm_mode = (EVP_CIPH_GCM_MODE == mode);
3810
+ const bool has_iv = iv_len >= 0 ;
3810
3811
3811
- if (is_gcm_mode == false && iv_len != expected_iv_len) {
3812
+ // Throw if no IV was passed and the cipher requires an IV
3813
+ if (!has_iv && expected_iv_len != 0 ) {
3814
+ char msg[128 ];
3815
+ snprintf (msg, sizeof (msg), " Missing IV for cipher %s" , cipher_type);
3816
+ return env ()->ThrowError (msg);
3817
+ }
3818
+
3819
+ // Throw if an IV was passed which does not match the cipher's fixed IV length
3820
+ if (is_gcm_mode == false && has_iv && iv_len != expected_iv_len) {
3812
3821
return env ()->ThrowError (" Invalid IV length" );
3813
3822
}
3814
3823
@@ -3820,11 +3829,13 @@ void CipherBase::InitIv(const char* cipher_type,
3820
3829
const bool encrypt = (kind_ == kCipher );
3821
3830
EVP_CipherInit_ex (ctx_, cipher, nullptr , nullptr , nullptr , encrypt );
3822
3831
3823
- if (is_gcm_mode &&
3824
- !EVP_CIPHER_CTX_ctrl (ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr )) {
3825
- EVP_CIPHER_CTX_free (ctx_);
3826
- ctx_ = nullptr ;
3827
- return env ()->ThrowError (" Invalid IV length" );
3832
+ if (is_gcm_mode) {
3833
+ CHECK (has_iv);
3834
+ if (!EVP_CIPHER_CTX_ctrl (ctx_, EVP_CTRL_GCM_SET_IVLEN, iv_len, nullptr )) {
3835
+ EVP_CIPHER_CTX_free (ctx_);
3836
+ ctx_ = nullptr ;
3837
+ return env ()->ThrowError (" Invalid IV length" );
3838
+ }
3828
3839
}
3829
3840
3830
3841
if (!EVP_CIPHER_CTX_set_key_length (ctx_, key_len)) {
@@ -3853,13 +3864,23 @@ void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
3853
3864
3854
3865
THROW_AND_RETURN_IF_NOT_STRING (args[0 ], " Cipher type" );
3855
3866
THROW_AND_RETURN_IF_NOT_BUFFER (args[1 ], " Key" );
3856
- THROW_AND_RETURN_IF_NOT_BUFFER (args[2 ], " IV" );
3867
+
3868
+ if (!args[2 ]->IsNull () && !Buffer::HasInstance (args[2 ])) {
3869
+ return env->ThrowTypeError (" IV must be a buffer" );
3870
+ }
3857
3871
3858
3872
const node::Utf8Value cipher_type (env->isolate (), args[0 ]);
3859
3873
ssize_t key_len = Buffer::Length (args[1 ]);
3860
3874
const char * key_buf = Buffer::Data (args[1 ]);
3861
- ssize_t iv_len = Buffer::Length (args[2 ]);
3862
- const char * iv_buf = Buffer::Data (args[2 ]);
3875
+ ssize_t iv_len;
3876
+ const char * iv_buf;
3877
+ if (args[2 ]->IsNull ()) {
3878
+ iv_buf = nullptr ;
3879
+ iv_len = -1 ;
3880
+ } else {
3881
+ iv_buf = Buffer::Data (args[2 ]);
3882
+ iv_len = Buffer::Length (args[2 ]);
3883
+ }
3863
3884
cipher->InitIv (*cipher_type, key_buf, key_len, iv_buf, iv_len);
3864
3885
}
3865
3886
0 commit comments