Skip to content

Commit

Permalink
crypto: use kNoAuthTagLength in InitAuthenticated
Browse files Browse the repository at this point in the history
Backport-PR-URL: #20706
PR-URL: #20225
Refs: #20039
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
  • Loading branch information
tniessen authored and addaleax committed May 14, 2018
1 parent eb21a6b commit f5e7010
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
30 changes: 21 additions & 9 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2622,7 +2622,7 @@ void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
void CipherBase::Init(const char* cipher_type,
const char* key_buf,
int key_buf_len,
int auth_tag_len) {
unsigned int auth_tag_len) {
HandleScope scope(env()->isolate());

#ifdef NODE_FIPS_MODE
Expand Down Expand Up @@ -2693,10 +2693,16 @@ void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
const node::Utf8Value cipher_type(args.GetIsolate(), args[0]);
const char* key_buf = Buffer::Data(args[1]);
ssize_t key_buf_len = Buffer::Length(args[1]);
CHECK(args[2]->IsInt32());

// Don't assign to cipher->auth_tag_len_ directly; the value might not
// represent a valid length at this point.
int auth_tag_len = args[2].As<v8::Int32>()->Value();
unsigned int auth_tag_len;
if (args[2]->IsUint32()) {
auth_tag_len = args[2].As<v8::Uint32>()->Value();
} else {
CHECK(args[2]->IsInt32() && args[2].As<v8::Int32>()->Value() == -1);
auth_tag_len = kNoAuthTagLength;
}

cipher->Init(*cipher_type, key_buf, key_buf_len, auth_tag_len);
}
Expand All @@ -2707,7 +2713,7 @@ void CipherBase::InitIv(const char* cipher_type,
int key_len,
const char* iv,
int iv_len,
int auth_tag_len) {
unsigned int auth_tag_len) {
HandleScope scope(env()->isolate());

const EVP_CIPHER* const cipher = EVP_get_cipherbyname(cipher_type);
Expand Down Expand Up @@ -2781,10 +2787,16 @@ void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
iv_buf = Buffer::Data(args[2]);
iv_len = Buffer::Length(args[2]);
}
CHECK(args[3]->IsInt32());

// Don't assign to cipher->auth_tag_len_ directly; the value might not
// represent a valid length at this point.
int auth_tag_len = args[3].As<v8::Int32>()->Value();
unsigned int auth_tag_len;
if (args[3]->IsUint32()) {
auth_tag_len = args[3].As<v8::Uint32>()->Value();
} else {
CHECK(args[3]->IsInt32() && args[3].As<v8::Int32>()->Value() == -1);
auth_tag_len = kNoAuthTagLength;
}

cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len, auth_tag_len);
}
Expand All @@ -2795,7 +2807,7 @@ static bool IsValidGCMTagLength(unsigned int tag_len) {
}

bool CipherBase::InitAuthenticated(const char *cipher_type, int iv_len,
int auth_tag_len) {
unsigned int auth_tag_len) {
CHECK(IsAuthenticatedMode());

if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr)) {
Expand All @@ -2805,7 +2817,7 @@ bool CipherBase::InitAuthenticated(const char *cipher_type, int iv_len,

const int mode = EVP_CIPHER_CTX_mode(ctx_);
if (mode == EVP_CIPH_CCM_MODE) {
if (auth_tag_len < 0) {
if (auth_tag_len == kNoAuthTagLength) {
char msg[128];
snprintf(msg, sizeof(msg), "authTagLength required for %s", cipher_type);
env()->ThrowError(msg);
Expand Down Expand Up @@ -2840,7 +2852,7 @@ bool CipherBase::InitAuthenticated(const char *cipher_type, int iv_len,
} else {
CHECK_EQ(mode, EVP_CIPH_GCM_MODE);

if (auth_tag_len >= 0) {
if (auth_tag_len != kNoAuthTagLength) {
if (!IsValidGCMTagLength(auth_tag_len)) {
char msg[50];
snprintf(msg, sizeof(msg),
Expand Down
7 changes: 4 additions & 3 deletions src/node_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,14 +365,15 @@ class CipherBase : public BaseObject {
void Init(const char* cipher_type,
const char* key_buf,
int key_buf_len,
int auth_tag_len);
unsigned int auth_tag_len);
void InitIv(const char* cipher_type,
const char* key,
int key_len,
const char* iv,
int iv_len,
int auth_tag_len);
bool InitAuthenticated(const char *cipher_type, int iv_len, int auth_tag_len);
unsigned int auth_tag_len);
bool InitAuthenticated(const char *cipher_type, int iv_len,
unsigned int auth_tag_len);
bool CheckCCMMessageLength(int message_len);
UpdateResult Update(const char* data, int len, unsigned char** out,
int* out_len);
Expand Down

0 comments on commit f5e7010

Please sign in to comment.