Yes, the docs has been updated. https://github.com/openssl/openssl/issues/4657
- Oknet 2017-11-06 15:25 GMT+08:00 Masaori Koshiba <masa...@apache.org>: > Nice catch! I didn't noticed that. Actually, when I added the AEAD > encrypt/decrypt code, I followed that wiki page. > > This is same question to https://github.com/openssl/openssl/issues/1624 > Also it looks like the latest docs has been changed. > > https://www.openssl.org/docs/manmaster/man3/EVP_ > EncryptInit.html#GCM-and-OCB-Modes > > - Masaori > > 2017年11月3日(金) 15:24 Chao Xu <ok...@apache.org>: > > > Hi dev, > > > > https://www.openssl.org/docs/man1.1.0/crypto/EVP_CIPHER_CTX_ctrl.html > > > > EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, tag); > > > > Sets the expected tag to taglen bytes from tag. This call is only legal > > when decrypting data and must be made before any data is processed (e.g. > > before any EVP_DecryptUpdate() call). For OCB mode the taglen must either > > be 16 or the value previously set via EVP_CTRL_AEAD_SET_TAG. > > According to the openssl 1.1.0 docs, it said the EVP_CTRL_AEAD_SET_TAG is > > only legal and must before any data is processed. > > > > But the sample code within wiki.openssl.org: > > https://wiki.openssl.org/index.php/EVP_Authenticated_ > Encryption_and_Decryption > > > > int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char > *aad, > > int aad_len, unsigned char *tag, unsigned char *key, unsigned char > *iv, > > int iv_len, unsigned char *plaintext) > > { > > EVP_CIPHER_CTX *ctx; > > int len; > > int plaintext_len; > > int ret; > > > > /* Create and initialise the context */ > > if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); > > > > /* Initialise the decryption operation. */ > > if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) > > handleErrors(); > > > > /* Set IV length. Not necessary if this is 12 bytes (96 bits) */ > > if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL)) > > handleErrors(); > > > > /* Initialise key and IV */ > > if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors(); > > > > /* Provide any AAD data. This can be called zero or more times as > > * required > > */ > > if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len)) > > handleErrors(); > > > > /* Provide the message to be decrypted, and obtain the plaintext > output. > > * EVP_DecryptUpdate can be called multiple times if necessary > > */ > > if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, > ciphertext_len)) > > handleErrors(); > > plaintext_len = len; > > > > /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ > > if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag)) > > handleErrors(); > > > > /* Finalise the decryption. A positive return value indicates > success, > > * anything else is a failure - the plaintext is not trustworthy. > > */ > > ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len); > > > > /* Clean up */ > > EVP_CIPHER_CTX_free(ctx); > > > > if(ret > 0) > > { > > /* Success */ > > plaintext_len += len; > > return plaintext_len; > > } > > else > > { > > /* Verify failed */ > > return -1; > > } > > } > > > > > > And our AE/AD decrypt function from QUIC: > > > > ``` > > bool > > QUICCrypto::_decrypt(uint8_t *plain, size_t &plain_len, size_t > > max_plain_len, const uint8_t *cipher, size_t cipher_len, > > uint64_t pkt_num, const uint8_t *ad, size_t ad_len, > > const uint8_t *key, size_t key_len, const uint8_t *iv, > > size_t iv_len, size_t tag_len) const > > { > > uint8_t nonce[EVP_MAX_IV_LENGTH] = {0}; > > size_t nonce_len = 0; > > _gen_nonce(nonce, nonce_len, pkt_num, iv, iv_len); > > > > EVP_CIPHER_CTX *aead_ctx; > > int len; > > > > if (!(aead_ctx = EVP_CIPHER_CTX_new())) { > > return false; > > } > > if (!EVP_DecryptInit_ex(aead_ctx, this->_aead, nullptr, nullptr, > > nullptr)) { > > return false; > > } > > if (!EVP_CIPHER_CTX_ctrl(aead_ctx, EVP_CTRL_AEAD_SET_IVLEN, nonce_len, > > nullptr)) { > > return false; > > } > > if (!EVP_DecryptInit_ex(aead_ctx, nullptr, nullptr, key, nonce)) { > > return false; > > } > > if (!EVP_DecryptUpdate(aead_ctx, nullptr, &len, ad, ad_len)) { > > return false; > > } > > > > if (cipher_len < tag_len) { > > return false; > > } > > cipher_len -= tag_len; > > if (!EVP_DecryptUpdate(aead_ctx, plain, &len, cipher, cipher_len)) { > > return false; > > } > > plain_len = len; > > > > if (!EVP_CIPHER_CTX_ctrl(aead_ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, > > const_cast<uint8_t *>(cipher + cipher_len))) { > > return false; > > } > > > > int ret = EVP_DecryptFinal_ex(aead_ctx, plain + len, &len); > > > > EVP_CIPHER_CTX_free(aead_ctx); > > > > if (ret > 0) { > > plain_len += len; > > return true; > > } else { > > Debug(tag, "Failed to decrypt"); > > return false; > > } > > } > > ``` > > > > - Oknet > > >