| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 329ac60 commit 624e516
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2891,6 +2891,10 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) { | |||
| 2891 | 2891 | return args.GetReturnValue().Set(false); | |
| 2892 | 2892 | } | |
| 2893 | 2893 | ||
| 2894 | + // TODO(tniessen): Throw if the authentication tag has already been set. | ||
| 2895 | + if (cipher->auth_tag_state_ == kAuthTagPassedToOpenSSL) | ||
| 2896 | + return args.GetReturnValue().Set(true); | ||
| 2897 | + | ||
| 2894 | 2898 | unsigned int tag_len = Buffer::Length(args[0]); | |
| 2895 | 2899 | const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get()); | |
| 2896 | 2900 | if (mode == EVP_CIPH_GCM_MODE) { | |
@@ -2923,6 +2927,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) { | |||
| 2923 | 2927 | ||
| 2924 | 2928 | // Note: we don't use std::min() here to work around a header conflict. | |
| 2925 | 2929 | cipher->auth_tag_len_ = tag_len; | |
| 2930 | + cipher->auth_tag_state_ = kAuthTagKnown; | ||
| 2926 | 2931 | if (cipher->auth_tag_len_ > sizeof(cipher->auth_tag_)) | |
| 2927 | 2932 | cipher->auth_tag_len_ = sizeof(cipher->auth_tag_); | |
| 2928 | 2933 | ||
@@ -2934,14 +2939,14 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) { | |||
| 2934 | 2939 | ||
| 2935 | 2940 | ||
| 2936 | 2941 | bool CipherBase::MaybePassAuthTagToOpenSSL() { | |
| 2937 | - if (!auth_tag_set_ && auth_tag_len_ != kNoAuthTagLength) { | ||
| 2942 | + if (auth_tag_state_ == kAuthTagKnown) { | ||
| 2938 | 2943 | if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), | |
| 2939 | 2944 | EVP_CTRL_AEAD_SET_TAG, | |
| 2940 | 2945 | auth_tag_len_, | |
| 2941 | 2946 | reinterpret_cast<unsigned char*>(auth_tag_))) { | |
| 2942 | 2947 | return false; | |
| 2943 | 2948 | } | |
| 2944 | - auth_tag_set_ = true; | ||
| 2949 | + auth_tag_state_ = kAuthTagPassedToOpenSSL; | ||
| 2945 | 2950 | } | |
| 2946 | 2951 | return true; | |
| 2947 | 2952 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -363,6 +363,11 @@ class CipherBase : public BaseObject { | |||
| 363 | 363 | kErrorMessageSize, | |
| 364 | 364 | kErrorState | |
| 365 | 365 | }; | |
| 366 | + enum AuthTagState { | ||
| 367 | + kAuthTagUnknown, | ||
| 368 | + kAuthTagKnown, | ||
| 369 | + kAuthTagPassedToOpenSSL | ||
| 370 | + }; | ||
| 366 | 371 | static const unsigned kNoAuthTagLength = static_cast<unsigned>(-1); | |
| 367 | 372 | ||
| 368 | 373 | void Init(const char* cipher_type, | |
@@ -404,7 +409,7 @@ class CipherBase : public BaseObject { | |||
| 404 | 409 | : BaseObject(env, wrap), | |
| 405 | 410 | ctx_(nullptr), | |
| 406 | 411 | kind_(kind), | |
| 407 | - auth_tag_set_(false), | ||
| 412 | + auth_tag_state_(kAuthTagUnknown), | ||
| 408 | 413 | auth_tag_len_(kNoAuthTagLength), | |
| 409 | 414 | pending_auth_failed_(false) { | |
| 410 | 415 | MakeWeak(); | |
@@ -413,7 +418,7 @@ class CipherBase : public BaseObject { | |||
| 413 | 418 | private: | |
| 414 | 419 | DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> ctx_; | |
| 415 | 420 | const CipherKind kind_; | |
| 416 | - bool auth_tag_set_; | ||
| 421 | + AuthTagState auth_tag_state_; | ||
| 417 | 422 | unsigned int auth_tag_len_; | |
| 418 | 423 | char auth_tag_[EVP_GCM_TLS_TAG_LEN]; | |
| 419 | 424 | bool pending_auth_failed_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -579,27 +579,35 @@ for (const test of TEST_CASES) { | |||
| 579 | 579 | } | |
| 580 | 580 | ||
| 581 | 581 | // Test that the authentication tag can be set at any point before calling | |
| 582 | - // final() in GCM mode. | ||
| 582 | + // final() in GCM or OCB mode. | ||
| 583 | 583 | { | |
| 584 | 584 | const plain = Buffer.from('Hello world', 'utf8'); | |
| 585 | 585 | const key = Buffer.from('0123456789abcdef', 'utf8'); | |
| 586 | 586 | const iv = Buffer.from('0123456789ab', 'utf8'); | |
| 587 | 587 | ||
| 588 | - const cipher = crypto.createCipheriv('aes-128-gcm', key, iv); | ||
| 589 | - const ciphertext = Buffer.concat([cipher.update(plain), cipher.final()]); | ||
| 590 | - const authTag = cipher.getAuthTag(); | ||
| 591 | - | ||
| 592 | - for (const authTagBeforeUpdate of [true, false]) { | ||
| 593 | - const decipher = crypto.createDecipheriv('aes-128-gcm', key, iv); | ||
| 594 | - if (authTagBeforeUpdate) { | ||
| 595 | - decipher.setAuthTag(authTag); | ||
| 596 | - } | ||
| 597 | - const resultUpdate = decipher.update(ciphertext); | ||
| 598 | - if (!authTagBeforeUpdate) { | ||
| 599 | - decipher.setAuthTag(authTag); | ||
| 588 | + for (const mode of ['gcm', 'ocb']) { | ||
| 589 | + for (const authTagLength of mode === 'gcm' ? [undefined, 8] : [8]) { | ||
| 590 | + const cipher = crypto.createCipheriv(`aes-128-${mode}`, key, iv, { | ||
| 591 | + authTagLength | ||
| 592 | + }); | ||
| 593 | + const ciphertext = Buffer.concat([cipher.update(plain), cipher.final()]); | ||
| 594 | + const authTag = cipher.getAuthTag(); | ||
| 595 | + | ||
| 596 | + for (const authTagBeforeUpdate of [true, false]) { | ||
| 597 | + const decipher = crypto.createDecipheriv(`aes-128-${mode}`, key, iv, { | ||
| 598 | + authTagLength | ||
| 599 | + }); | ||
| 600 | + if (authTagBeforeUpdate) { | ||
| 601 | + decipher.setAuthTag(authTag); | ||
| 602 | + } | ||
| 603 | + const resultUpdate = decipher.update(ciphertext); | ||
| 604 | + if (!authTagBeforeUpdate) { | ||
| 605 | + decipher.setAuthTag(authTag); | ||
| 606 | + } | ||
| 607 | + const resultFinal = decipher.final(); | ||
| 608 | + const result = Buffer.concat([resultUpdate, resultFinal]); | ||
| 609 | + assert(result.equals(plain)); | ||
| 610 | + } | ||
| 600 | 611 | } | |
| 601 | - const resultFinal = decipher.final(); | ||
| 602 | - const result = Buffer.concat([resultUpdate, resultFinal]); | ||
| 603 | - assert(result.equals(plain)); | ||
| 604 | 612 | } | |
| 605 | 613 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments