@@ -2790,6 +2790,10 @@ void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
27902790}
27912791
27922792
2793+ static bool IsValidGCMTagLength (unsigned int tag_len) {
2794+ return tag_len == 4 || tag_len == 8 || tag_len >= 12 && tag_len <= 16 ;
2795+ }
2796+
27932797bool CipherBase::InitAuthenticated (const char *cipher_type, int iv_len,
27942798 int auth_tag_len) {
27952799 CHECK (IsAuthenticatedMode ());
@@ -2799,7 +2803,8 @@ bool CipherBase::InitAuthenticated(const char *cipher_type, int iv_len,
27992803 return false ;
28002804 }
28012805
2802- if (EVP_CIPHER_CTX_mode (ctx_) == EVP_CIPH_CCM_MODE) {
2806+ const int mode = EVP_CIPHER_CTX_mode (ctx_);
2807+ if (mode == EVP_CIPH_CCM_MODE) {
28032808 if (auth_tag_len < 0 ) {
28042809 char msg[128 ];
28052810 snprintf (msg, sizeof (msg), " authTagLength required for %s" , cipher_type);
@@ -2832,6 +2837,21 @@ bool CipherBase::InitAuthenticated(const char *cipher_type, int iv_len,
28322837 } else {
28332838 max_message_size_ = INT_MAX;
28342839 }
2840+ } else {
2841+ CHECK_EQ (mode, EVP_CIPH_GCM_MODE);
2842+
2843+ if (auth_tag_len >= 0 ) {
2844+ if (!IsValidGCMTagLength (auth_tag_len)) {
2845+ char msg[50 ];
2846+ snprintf (msg, sizeof (msg),
2847+ " Invalid GCM authentication tag length: %u" , auth_tag_len);
2848+ env ()->ThrowError (msg);
2849+ return false ;
2850+ }
2851+
2852+ // Remember the given authentication tag length for later.
2853+ auth_tag_len_ = auth_tag_len;
2854+ }
28352855 }
28362856
28372857 return true ;
@@ -2867,7 +2887,7 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
28672887 // Only callable after Final and if encrypting.
28682888 if (cipher->ctx_ != nullptr ||
28692889 cipher->kind_ != kCipher ||
2870- cipher->auth_tag_len_ == 0 ) {
2890+ cipher->auth_tag_len_ == kNoAuthTagLength ) {
28712891 return args.GetReturnValue ().SetUndefined ();
28722892 }
28732893
@@ -2892,7 +2912,14 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
28922912 unsigned int tag_len = Buffer::Length (args[0 ]);
28932913 const int mode = EVP_CIPHER_CTX_mode (cipher->ctx_ );
28942914 if (mode == EVP_CIPH_GCM_MODE) {
2895- if (tag_len > 16 || (tag_len < 12 && tag_len != 8 && tag_len != 4 )) {
2915+ if (cipher->auth_tag_len_ != kNoAuthTagLength &&
2916+ cipher->auth_tag_len_ != tag_len) {
2917+ char msg[50 ];
2918+ snprintf (msg, sizeof (msg),
2919+ " Invalid GCM authentication tag length: %u" , tag_len);
2920+ return cipher->env ()->ThrowError (msg);
2921+ }
2922+ if (!IsValidGCMTagLength (tag_len)) {
28962923 char msg[125 ];
28972924 snprintf (msg, sizeof (msg),
28982925 " Permitting authentication tag lengths of %u bytes is deprecated. "
@@ -2929,7 +2956,8 @@ bool CipherBase::SetAAD(const char* data, unsigned int len, int plaintext_len) {
29292956 if (!CheckCCMMessageLength (plaintext_len))
29302957 return false ;
29312958
2932- if (kind_ == kDecipher && !auth_tag_set_ && auth_tag_len_ > 0 ) {
2959+ if (kind_ == kDecipher && !auth_tag_set_ && auth_tag_len_ > 0 &&
2960+ auth_tag_len_ != kNoAuthTagLength ) {
29332961 if (!EVP_CIPHER_CTX_ctrl (ctx_,
29342962 EVP_CTRL_CCM_SET_TAG,
29352963 auth_tag_len_,
@@ -2982,7 +3010,7 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
29823010
29833011 // on first update:
29843012 if (kind_ == kDecipher && IsAuthenticatedMode () && auth_tag_len_ > 0 &&
2985- !auth_tag_set_) {
3013+ auth_tag_len_ != kNoAuthTagLength && !auth_tag_set_) {
29863014 EVP_CIPHER_CTX_ctrl (ctx_,
29873015 EVP_CTRL_GCM_SET_TAG,
29883016 auth_tag_len_,
0 commit comments