Subject: Problems verifying sample packet protection in appendix A of Using TLS to Secure QUIC

From: <[email-masked]>
Date: Tue, 14 Jul 2020 16:05:53 +0000

Hi,

I'm working through Appendix A of the QUIC TLS doc to check my understanding, but am having trouble decrypting the sample client initial packet.  I'm unsure if I've made a silly error or two, or if I've made one or more incorrect assumptions.  Or both.

The functions I'm using are the OpenSSL EVP ones.  I'm attempting to follow the recipe here:
https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Decryption_using_GCM_mode in conjunction with the draft RFC.

EVP_CIPHER_CTX_new()

EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL)

EVP_DecryptInit_ex(ctx, NULL, NULL, client_key, iv)         where the client key is 0x175257a31eb09dea9366d8bb79ad80ba and the iv is 0x6b26114b9cba2b63a9e8dd4f

EVP_DecryptUpdate(ctx, NULL, &len, pUnprotectedHeader, headerLength)           where the unprotected header is 0xc3ff00001d088394c8f03e5157080000449e00000002 - this I believe is the Additional Data required

EVP_DecryptUpdate(ctx, decryptedPayload, &len, pPayload, payloadLength-16))   here I'm passing in the encrypted payload beginning 0xfb66bc5f and ending 0xe82a4d919d48, length 1162.  I'm assuming that the final 16 bytes of the payload is the authentication tag so am not passing it in here.  Note that if this assumption about the authentication tag is correct, I think it could be more clearly stated in the draft RFC.

EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) where tag is the final 16 bytes of the encrypted payload, ie 0x43b1ca70 a2d8d3f7 25ead139 1377dcc0

EVP_DecryptFinal_ex(ctx, decryptedPayload + len, &len)

Everything seems OK until the EVP_DecryptFinal_ex() call which fails.

Is there anything obviously wrong with the above?  I've not posted the full source code as I'm not asking people to check my working, I'm really asking if my assumptions are correct, am I using the correct functions, input data etc.

Thanks in advance

Tim

---

From: Nick Harper <[email-masked]>
Date: Tue, 14 Jul 2020 11:47:03 -0700

On Tue, Jul 14, 2020 at 9:06 AM <[email-masked]> wrote:

> Hi,
>
>
>
> I’m working through Appendix A of the QUIC TLS doc to check my
> understanding, but am having trouble decrypting the sample client initial
> packet.  I’m unsure if I’ve made a silly error or two, or if I’ve made one
> or more incorrect assumptions.  Or both.
>
>
>
> The functions I’m using are the OpenSSL EVP ones.  I’m attempting to
> follow the recipe here:
>
>
> EVP_DecryptInit_ex(ctx, NULL, NULL, client_key, iv)         where the
> client key is 0x175257a31eb09dea9366d8bb79ad80ba and the iv is
> 0x6b26114b9cba2b63a9e8dd4f
>

You need to compute the nonce from the IV and the packet number. I assume
what the openssl documentation refers to as an IV is actually the nonce as
described in RFC 5116.

>
>
> EVP_DecryptUpdate(ctx, NULL, &len, pUnprotectedHeader,
> headerLength)           where the unprotected header is
> 0xc3ff00001d088394c8f03e5157080000449e00000002 – this I believe is the
> Additional Data required
>
>
>
> EVP_DecryptUpdate(ctx, decryptedPayload, &len, pPayload,
> payloadLength-16))   here I’m passing in the encrypted payload beginning
> 0xfb66bc5f and ending 0xe82a4d919d48, length 1162.  I’m assuming that the
> final 16 bytes of the payload is the authentication tag so am not passing
> it in here.  Note that if this assumption about the authentication tag is
> correct, I think it could be more clearly stated in the draft RFC.
>

This is a quirk of the openssl API unfortunately. An AEAD decryption
operation should take 4 inputs: the key, the nonce, the associated data,
and the ciphertext. The ciphertext, as defined by RFC 5116, includes the
tag. There's no requirement on the structure of an AEAD's ciphertext,
including that some portion of the ciphertext be able to be identified as a
tag. AES-GCM does have this structure where the tag is at the end of the
ciphertext, and unfortunately openssl makes that part of the api for the
AEAD open operation, even though someone using it should never have to know
that detail of the AES-GCM algorithm.

>
>
> EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) where tag is the
> final 16 bytes of the encrypted payload, ie 0x43b1ca70 a2d8d3f7 25ead139
> 1377dcc0
>
>
>
> Is there anything obviously wrong with the above?  I’ve not posted the
> full source code as I’m not asking people to check my working, I’m really
> asking if my assumptions are correct, am I using the correct functions,
> input data etc.
>
>
>
> Thanks in advance
>
>
>
> Tim
>

---

From: <[email-masked]>
Date: Wed, 15 Jul 2020 10:28:49 +0000

Thanks for that Nick, very helpful, even better my code is now working 😊

From: Nick Harper <[email-masked]>
Sent: 14 July 2020 19:47
To: Jebb,TR,Tim,VIE R <[email-masked]>
Cc: IETF QUIC WG <[email-masked]>
Subject: Re: Problems verifying sample packet protection in appendix A of Using TLS to Secure QUIC

On Tue, Jul 14, 2020 at 9:06 AM <[email-masked]<mailto:[email-masked]>> wrote:
Hi,

I’m working through Appendix A of the QUIC TLS doc to check my understanding, but am having trouble decrypting the sample client initial packet.  I’m unsure if I’ve made a silly error or two, or if I’ve made one or more incorrect assumptions.  Or both.

The functions I’m using are the OpenSSL EVP ones.  I’m attempting to follow the recipe here:
https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Decryption_using_GCM_mode in conjunction with the draft RFC.

EVP_CIPHER_CTX_new()

You need to compute the nonce from the IV and the packet number. I assume what the openssl documentation refers to as an IV is actually the nonce as described in RFC 5116.

EVP_DecryptUpdate(ctx, NULL, &len, pUnprotectedHeader, headerLength)           where the unprotected header is 0xc3ff00001d088394c8f03e5157080000449e00000002 – this I believe is the Additional Data required

EVP_DecryptUpdate(ctx, decryptedPayload, &len, pPayload, payloadLength-16))   here I’m passing in the encrypted payload beginning 0xfb66bc5f and ending 0xe82a4d919d48, length 1162.  I’m assuming that the final 16 bytes of the payload is the authentication tag so am not passing it in here.  Note that if this assumption about the authentication tag is correct, I think it could be more clearly stated in the draft RFC.

This is a quirk of the openssl API unfortunately. An AEAD decryption operation should take 4 inputs: the key, the nonce, the associated data, and the ciphertext. The ciphertext, as defined by RFC 5116, includes the tag. There's no requirement on the structure of an AEAD's ciphertext, including that some portion of the ciphertext be able to be identified as a tag. AES-GCM does have this structure where the tag is at the end of the ciphertext, and unfortunately openssl makes that part of the api for the AEAD open operation, even though someone using it should never have to know that detail of the AES-GCM algorithm.

Is there anything obviously wrong with the above?  I’ve not posted the full source code as I’m not asking people to check my working, I’m really asking if my assumptions are correct, am I using the correct functions, input data etc.

Thanks in advance

Tim

---

From: <[email-masked]>
Date: Tue, 21 Jul 2020 15:42:30 +0000

Hi,

Unfortunately I’m still having problems removing packet protection.

Although I can now successfully process the sample packet in the draft RFC (thanks to Nick), my first attempt at a captured packet is failing (using the same code).  I can’t see where I’m going wrong.  It’s the header protection removal I’m having problems with.

If it’s not too much to ask, would anyone be in a position to process the client initial packet below, and give the intermediate values along the lines of those given in appendix A?

The packet is

uint8_t protected_frame1[302] =
{0xc8,0xff,0x00,0x00,0x1b,0x11,0x76,0xf8,0x1a,0x55,0x88,0xb2,0xf2,0x5c,0x5a,0xb6,
0xdb,0xd4,0x61,0xa8,0xd7,0x49,0xe1,0x03,0xc5,0xef,0x02,0x00,0x41,0x10,0xb0,0xbd,
0x14,0x04,0xf5,0x35,0x17,0x7f,0xcb,0xcf,0xd5,0xf0,0x6d,0x24,0xff,0xde,0x66,0xed,
0xf1,0x0d,0xf7,0x92,0x05,0x66,0x6b,0x18,0x51,0x18,0x9f,0x54,0xa0,0x92,0x7d,0xf2,
0x30,0xb5,0xcb,0xd7,0xc9,0x6d,0xe6,0xc5,0x76,0xe5,0x59,0x42,0x23,0x1e,0xc8,0x53,
0x9f,0xf2,0x82,0xe2,0xcf,0xd7,0x53,0x83,0x8b,0x12,0x53,0xce,0x19,0x5c,0xd6,0x32,
0x22,0x5d,0xe0,0xca,0x2e,0x37,0x42,0xc1,0xda,0x08,0x4d,0xa4,0xd1,0x18,0xc7,0x75,
0x7c,0x3c,0xae,0x3b,0xf6,0x95,0xa2,0xc6,0x83,0x99,0x97,0x9f,0x98,0x0d,0xdb,0xa6,
0xa9,0x77,0xbd,0xba,0x31,0x20,0xb2,0x8b,0xe8,0x0e,0x0b,0xe9,0xe0,0x89,0x3f,0x05,
0x8d,0xdd,0x8d,0x7b,0xe3,0x90,0xde,0xd6,0x68,0x79,0x62,0x8d,0x47,0xb7,0x47,0x78,
0x17,0x4e,0x9e,0x65,0x93,0xce,0x81,0x17,0xbf,0x5f,0x4b,0x16,0xb8,0x8d,0xe3,0x48,
0x4f,0x97,0x7e,0x22,0xde,0xd8,0x6e,0xb2,0x9b,0x00,0xbd,0xa4,0xa4,0xfb,0x74,0x9c,
0xee,0x83,0x29,0xd6,0xf1,0x32,0xb3,0x91,0xbb,0x6e,0x9a,0x93,0x71,0x61,0xc4,0xd9,
0xeb,0x30,0x2f,0x43,0x73,0x20,0xe4,0x78,0x29,0xff,0xe7,0x19,0x11,0x97,0xe8,0x33,
0xd5,0x47,0xd1,0x6e,0xc1,0xdc,0x91,0x0f,0xd6,0xfe,0xac,0x64,0x94,0x99,0x00,0xb9,
0x91,0x79,0xf6,0x1c,0x11,0x85,0x44,0xd1,0x9f,0x56,0xbe,0x3f,0x4f,0x52,0xa7,0x2c,
0x52,0x3d,0x2b,0x41,0xe0,0x42,0xa7,0x4c,0xbc,0x31,0xd4,0xb3,0xa4,0x55,0xde,0xce,
0x0c,0xbe,0x9d,0x29,0x59,0xdf,0xf8,0xfb,0x53,0x0c,0x64,0x2e,0xb5,0x2d,0xa4,0x3d,
0xea,0xf9,0x90,0x8c,0x1b,0x0b,0xd5,0x0d,0x44,0x59,0xe0,0xe4,0x74,0x85};

EVP_CIPHER_CTX_new()

Thanks in advance

Tim

---

From: <[email-masked]>
Date: Wed, 29 Jul 2020 12:36:08 +0000

Just an update:  I’ve got to the bottom of my problem:  I hadn’t realised that the salt changes between drafts of the RFC!

From: [email-masked] <[email-masked]>
Sent: 21 July 2020 16:43
To: [email-masked]
Cc: [email-masked]
Subject: RE: Problems verifying sample packet protection in appendix A of Using TLS to Secure QUIC

Hi,

The packet is

From: Nick Harper <[email-masked]<mailto:[email-masked]>>
Sent: 14 July 2020 19:47
To: Jebb,TR,Tim,VIE R <[email-masked]<mailto:[email-masked]>>
Cc: IETF QUIC WG <[email-masked]<mailto:[email-masked]>>
Subject: Re: Problems verifying sample packet protection in appendix A of Using TLS to Secure QUIC

EVP_CIPHER_CTX_new()

Thanks in advance

Tim