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
> >
>

Reply via email to