Re: Obtaining a TLS session key
On Fri, Feb 8, 2013 at 12:11 AM, T J jordan.tre...@gmail.com wrote: TLS keying material exporter, i.e., SSL_export_keying_material(), will make your life much easier if you are just looking for a mechanism to derive suitable keys for other uses assuming you are using recent enough OpenSSL. That tls_openssl.c file I mentioned above has an example of this, too. Thanks very much Jouni - I think that will work nicely! Now if only there was some documentation on it... I happened to had implemented the ugly way before and reviewed the RFC describing this functionality, so never had to try to find documentation.. RFC 5705 describes the mechanism it high level. I'm not sure whether the OpenSSL implementation is documented somewhere. So to get a key, I would just establish the TLS connection, then use: if (!SSL_export_keying_material(mySsl, key, key_len, label, label_len, NULL, 0, 0)) { //handle error } before closing the connection? After having completed TLS handshake and before closing the connection, yes. Do that on both ends and I have my symmetric keys for use in my app(s). (My app uses a completely seperate radio path for bulk data encrypted using specialised hardware - hence my requirement for a key.) That's pretty much what I'm using this for, too, with EAP, i.e., only authenticate and derive the key with TLS. SSL_export_keying_material() works fine for that as long as you do not need to meet some protocol design where key derivation is defined in a way that does not match the functionality defined in RFC 5705. - Jouni __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On Thu, Feb 07, 2013 at 08:00:42PM +1300, Trevor Jordan wrote: It is bad practice to clone keys. You should also not depend on OpenSSL negotiating a particular algorithm. OpenSSL's key are for the OpenSSL session only. Keys for your application should be the result of a suitably independent KDF. Well I wouldn't be cloning keys if I'm not using the OpenSSL session. Once keys have been negotiated, I intend to immediately close the connection and only reuse the session if I need a new key. The keys will be slightly used, they encrypted the finished message and likely also any close notify alerts sent to terminate the session. I'll also make sure both server and client only use one algorithm. This is not your typical internet based client/public server senario. I just need a certificate based authenticated key which SSL/TLS can provide. I would still consider deriving new keys, at the very least you'll probably want a new IV. You also need a shared secret for HMAC, or were you planning to use GCM? Why not just continue with TLS, you've gone to all the trouble of agreeing on keys, ... the rest is pretty much bulk crypto. Otherwise, you need to re-invent the wheel with your own stream protocol based on the agreed keys, this is always harder to get right than you might guess. -- Viktor. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
s-s3-tmp.key_block s-s3-tmp.key_block_length I think, these are the variables you are looking for.. Memory for the key_block is allocated in ssl3_setup_key_block() or tls1_setup_key_block() functions. Key Block contains keys and IVs in the following order as specified in RFC. client write MAC key server write MAC key client write encryption key server write encryption key client write IV(if applicable) server write IV(if applicable) Thanks, Thulasi. On Thu, Feb 7, 2013 at 3:42 AM, T J jordan.tre...@gmail.com wrote: Sorry to keep hammering away at this, but I think I am missing something here. OpenSSL does all this for a TLS connection anyway right? I mean, after a handshake, encryption keys, IV's etc are generated so that the TLS connection can use them for encrypting/decrypting data. Surely I shouldn't have to reinvent the wheel and do what OpenSSL already does... All I want to do is get those keys, after the connection has been established and use them directly in my own app instead of using the SSL connection normally. Isn't there something like ssl-s3-final_key ? On 01/02/13 17:26, Viktor Dukhovni wrote: On Fri, Feb 01, 2013 at 10:05:15AM +1300, T J wrote: These are sufficient to generate a session unique key via a suitable KDF salted with an application-specific string. OK, great. So I get the master key and run it through the a KDF and I get a 256 bit encryption key for use in my application. Sounds easy... Not just the master key, also the client_random, server_random (from the SSL handshake) and a *fixed* application-specific salt, that yields a different key than another application might derive under the same conditions. Question 1: previously, you said: ... the expansion function of HKDF is a reasonable choice. ... but now you mention salt which implies I should also use the extraction stage. If the salt is random, doesn't that mean the client and server would end up with different keys? The salt is the same on client and server. Question 2: Where do the client_random and server_random values come from and what are they for? The SSL handshake, IIRC the master secret does not change when a session is reused, but client random and server_random do. __**__**__ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On Thu, Feb 7, 2013 at 9:00 AM, Trevor Jordan jordan.tre...@gmail.com wrote: From what I understand so far, the KeyBlock is the place to look for the key? It's just a matter of getting the sizes and order of the individual Keys and IV's so that I can extract the bits I need. Any pointers in that area? While it is technically possible to extract keys (search for tls_openssl.c in hostap.git for an example), I would not recommend doing this unless you really have to get a specific key derivation mechanism matching with a defined use. This will be ugly and OpenSSL version dependent.. TLS keying material exporter, i.e., SSL_export_keying_material(), will make your life much easier if you are just looking for a mechanism to derive suitable keys for other uses assuming you are using recent enough OpenSSL. That tls_openssl.c file I mentioned above has an example of this, too. - Jouni __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
From what I understand so far, the KeyBlock is the place to look for the key? It's just a matter of getting the sizes and order of the individual Keys and IV's so that I can extract the bits I need. Any pointers in that area? While it is technically possible to extract keys (search for tls_openssl.c in hostap.git for an example), I would not recommend doing this unless you really have to get a specific key derivation mechanism matching with a defined use. This will be ugly and OpenSSL version dependent.. TLS keying material exporter, i.e., SSL_export_keying_material(), will make your life much easier if you are just looking for a mechanism to derive suitable keys for other uses assuming you are using recent enough OpenSSL. That tls_openssl.c file I mentioned above has an example of this, too. - Jouni Thanks very much Jouni - I think that will work nicely! Now if only there was some documentation on it... So to get a key, I would just establish the TLS connection, then use: if (!SSL_export_keying_material(mySsl, key, key_len, label, label_len, NULL, 0, 0)) { //handle error } before closing the connection? Do that on both ends and I have my symmetric keys for use in my app(s). (My app uses a completely seperate radio path for bulk data encrypted using specialised hardware - hence my requirement for a key.) __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
Sorry to keep hammering away at this, but I think I am missing something here. OpenSSL does all this for a TLS connection anyway right? I mean, after a handshake, encryption keys, IV's etc are generated so that the TLS connection can use them for encrypting/decrypting data. Surely I shouldn't have to reinvent the wheel and do what OpenSSL already does... All I want to do is get those keys, after the connection has been established and use them directly in my own app instead of using the SSL connection normally. Isn't there something like ssl-s3-final_key ? On 01/02/13 17:26, Viktor Dukhovni wrote: On Fri, Feb 01, 2013 at 10:05:15AM +1300, T J wrote: These are sufficient to generate a session unique key via a suitable KDF salted with an application-specific string. OK, great. So I get the master key and run it through the a KDF and I get a 256 bit encryption key for use in my application. Sounds easy... Not just the master key, also the client_random, server_random (from the SSL handshake) and a *fixed* application-specific salt, that yields a different key than another application might derive under the same conditions. Question 1: previously, you said: ... the expansion function of HKDF is a reasonable choice. ... but now you mention salt which implies I should also use the extraction stage. If the salt is random, doesn't that mean the client and server would end up with different keys? The salt is the same on client and server. Question 2: Where do the client_random and server_random values come from and what are they for? The SSL handshake, IIRC the master secret does not change when a session is reused, but client random and server_random do. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On Thu, Feb 07, 2013 at 11:12:13AM +1300, T J wrote: Sorry to keep hammering away at this, but I think I am missing something here. OpenSSL does all this for a TLS connection anyway right? I mean, after a handshake, encryption keys, IV's etc are generated so that the TLS connection can use them for encrypting/decrypting data. Surely I shouldn't have to reinvent the wheel and do what OpenSSL already does... All I want to do is get those keys, after the connection has been established and use them directly in my own app instead of using the SSL connection normally. Isn't there something like ssl-s3-final_key ? It is bad practice to clone keys. You should also not depend on OpenSSL negotiating a particular algorithm. OpenSSL's key are for the OpenSSL session only. Keys for your application should be the result of a suitably independent KDF. -- Viktor. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On 7/02/2013 7:11 p.m., Viktor Dukhovni wrote: On Thu, Feb 07, 2013 at 11:12:13AM +1300, T J wrote: Sorry to keep hammering away at this, but I think I am missing something here. OpenSSL does all this for a TLS connection anyway right? I mean, after a handshake, encryption keys, IV's etc are generated so that the TLS connection can use them for encrypting/decrypting data. Surely I shouldn't have to reinvent the wheel and do what OpenSSL already does... All I want to do is get those keys, after the connection has been established and use them directly in my own app instead of using the SSL connection normally. Isn't there something like ssl-s3-final_key ? It is bad practice to clone keys. You should also not depend on OpenSSL negotiating a particular algorithm. OpenSSL's key are for the OpenSSL session only. Keys for your application should be the result of a suitably independent KDF. Well I wouldn't be cloning keys if I'm not using the OpenSSL session. Once keys have been negotiated, I intend to immediately close the connection and only reuse the session if I need a new key. I'll also make sure both server and client only use one algorithm. This is not your typical internet based client/public server senario. I just need a certificate based authenticated key which SSL/TLS can provide. From what I understand so far, the KeyBlock is the place to look for the key? It's just a matter of getting the sizes and order of the individual Keys and IV's so that I can extract the bits I need. Any pointers in that area? __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On Wed, Jan 30, 2013 at 06:15:27PM +, Viktor Dukhovni wrote: If the OP does not mind potential future binary compatibility issues, and is willing to use non-public interfaces, then the master secret can be accessed via: SSL *ssl; /* ... */ SSL_SESSION *sess = SSL_get_session(ssl); /* Internal interface */ int mlen = sess-master_key_length; unsigned char *mkey = sess-master_key; /* Internal interface + The handshake protocol MUST NOT be SSLv2 */ unsigned char *crand = ssl-s3-client_random; /* SSL3_RANDOM_SIZE */ unsigned char *srand = ssl-s3-server_random; /* SSL3_RANDOM_SIZE */ These are sufficient to generate a session unique key via a suitable KDF salted with an application-specific string. OK, great. So I get the master key and run it through the a KDF and I get a 256 bit encryption key for use in my application. Sounds easy... Question 1: previously, you said: ... the expansion function of HKDF is a reasonable choice. ... but now you mention salt which implies I should also use the extraction stage. If the salt is random, doesn't that mean the client and server would end up with different keys? Question 2: Where do the client_random and server_random values come from and what are they for? __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On Fri, Feb 01, 2013 at 10:05:15AM +1300, T J wrote: These are sufficient to generate a session unique key via a suitable KDF salted with an application-specific string. OK, great. So I get the master key and run it through the a KDF and I get a 256 bit encryption key for use in my application. Sounds easy... Not just the master key, also the client_random, server_random (from the SSL handshake) and a *fixed* application-specific salt, that yields a different key than another application might derive under the same conditions. Question 1: previously, you said: ... the expansion function of HKDF is a reasonable choice. ... but now you mention salt which implies I should also use the extraction stage. If the salt is random, doesn't that mean the client and server would end up with different keys? The salt is the same on client and server. Question 2: Where do the client_random and server_random values come from and what are they for? The SSL handshake, IIRC the master secret does not change when a session is reused, but client random and server_random do. -- Viktor. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On 1/30/2013 6:42 AM, Viktor Dukhovni wrote: On Wed, Jan 30, 2013 at 05:29:51PM +1300, T J wrote: How does one obtain the session key from a SSL structure after a successful TLS handshake? You don't, but, you shold instead obtain the tls-unique channel binding data ( https://tools.ietf.org/html/rfc5929#section-3 ) and run the result through a KDF (HKDF should work well) on both ends to obtain a suitable key for a symmetric algorithm of your choice. Sorry, not such a good idea. As I read RFC5929 and the TLS 1.2 RFC, it seems that despite some vaguely promising language in RFC5929, the tls-unique value is *not* suitable as the basis of an encryption key for the following reasons: 1. It is quite vague (underspecified) if and when the form of the finished message used as the tls-unique value is A) sent in the clear B) The already encrypted form of the message as sent over the network or C) The plaintext passed to the TLS encryption mechanism before transmission. In interpretation A and B the value is known to any attackers, while in interpretation C it is known to attackers only if the negotiated TLS encryption is NULL or weak. 2. The TLS 1.2 RFC seems clear that the raw input tls-unique value will often be only 12 bytes (96 bits) which is not enough input to generate a 128 bit or stronger encryption key, no matter how clever the KDF. It seems that the only proper use of the tls-unique value is as a way to use an outside channel to authenticate the TLS session, not the other way around. The use that seems to be suggested in the text of RFC5929 is to use it as an extra input to any strong authentication protocols (such as SRP or HTTP-digest) done over the TLS session to prove to the other end that the authentication is for this TLS session, and not for some TLS session you are having with a man in the middle. This is safe even if an attacker knows the value as long as he cannot force both ends of a MitM compromised connection to use the same value and cannot compute the needed changes in authentication messages to compensate for the difference between the two tls-unique values from the two halfs of the connection. (snip code to extract the tls-unique binary value from an SSL_CTX handle without a specific API for this task) For HKDF see: https://tools.ietf.org/html/rfc5869 Enjoy Jakob -- Jakob Bohm, CIO, Partner, WiseMo A/S. http://www.wisemo.com Transformervej 29, 2730 Herlev, Denmark. Direct +45 31 13 16 10 This public discussion message is non-binding and may contain errors. WiseMo - Remote Service Management for PCs, Phones and Embedded __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On Wed, Jan 30, 2013 at 07:03:09PM +0100, Jakob Bohm wrote: You don't, but, you shold instead obtain the tls-unique channel binding data ( https://tools.ietf.org/html/rfc5929#section-3 ) and run the result through a KDF (HKDF should work well) on both ends to obtain a suitable key for a symmetric algorithm of your choice. Sorry, not such a good idea. As I read RFC5929 and the TLS 1.2 RFC, it seems that despite some vaguely promising language in RFC5929, the tls-unique value is *not* suitable as the basis of an encryption key for the following reasons: 1. It is quite vague (underspecified) if and when the form of the finished message used as the tls-unique value is A) sent in the clear B) The already encrypted form of the message as sent over the network or C) The plaintext passed to the TLS encryption mechanism before transmission. In interpretation A and B the value is known to any attackers, while in interpretation C it is known to attackers only if the negotiated TLS encryption is NULL or weak. The finished message is always sent (by both parties) after ChangeCipherSpec, and thus always encrypted, provided the handshake did not negotiate an eNULL bulk cipher. This is explicitly stated the TLS RFCs. 2. The TLS 1.2 RFC seems clear that the raw input tls-unique value will often be only 12 bytes (96 bits) which is not enough input to generate a 128 bit or stronger encryption key, no matter how clever the KDF. This is fair, the tls-unique value is in practice only 96 bits. And indeed its intended use is channel-binding with GSSAPI, ... If 96-bits is not enough, one needs to get at the master secret on both sides, and run that through a KDF together with client and server random plus a suitable application-specific salt. Does OpenSSL provide a public interface for getting at the master secret or otherwise generating application-specific derived keys? -- Viktor. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On 1/30/2013 7:15 PM, Viktor Dukhovni wrote: On Wed, Jan 30, 2013 at 07:03:09PM +0100, Jakob Bohm wrote: You don't, but, you shold instead obtain the tls-unique channel binding data ( https://tools.ietf.org/html/rfc5929#section-3 ) and run the result through a KDF (HKDF should work well) on both ends to obtain a suitable key for a symmetric algorithm of your choice. Sorry, not such a good idea. As I read RFC5929 and the TLS 1.2 RFC, it seems that despite some vaguely promising language in RFC5929, the tls-unique value is *not* suitable as the basis of an encryption key for the following reasons: 1. It is quite vague (underspecified) if and when the form of the finished message used as the tls-unique value is A) sent in the clear B) The already encrypted form of the message as sent over the network or C) The plaintext passed to the TLS encryption mechanism before transmission. In interpretation A and B the value is known to any attackers, while in interpretation C it is known to attackers only if the negotiated TLS encryption is NULL or weak. The finished message is always sent (by both parties) after ChangeCipherSpec, and thus always encrypted, provided the handshake did not negotiate an eNULL bulk cipher. This is explicitly stated the TLS RFCs. In the basic non-renegotiation form of a TLS connection, the Finished messages are the only handshake messages that are encrypted (Protected). Different descriptions of the protocol may thus (with no change in meaning) refer to the encryption of that message to be either part of the message or part of its framing. Unfortunately neither the tls-unique spec at https://tools.ietf.org/html/rfc5929#section-3.1 nor version 1.2 of the TLS spec at https://tools.ietf.org/html/rfc5246#section-7.4.9 specify (without a search of all other document parts) if the Finished struct, not the TLS record layer message containing it refers to the encrypted or unencrypted message, hence the confusion. Adding an appropriate adjective such as unencrypted or plaintext to this phrase in RFC5929 would have avoided the confusion and risk of incorrect implementations (remember the HTTP deflate debacle caused by similar vagueness). 2. The TLS 1.2 RFC seems clear that the raw input tls-unique value will often be only 12 bytes (96 bits) which is not enough input to generate a 128 bit or stronger encryption key, no matter how clever the KDF. This is fair, the tls-unique value is in practice only 96 bits. And indeed its intended use is channel-binding with GSSAPI, ... If 96-bits is not enough, one needs to get at the master secret on both sides, and run that through a KDF together with client and server random plus a suitable application-specific salt. Thanks, agreed. Enjoy Jakob -- Jakob Bohm, CIO, Partner, WiseMo A/S. http://www.wisemo.com Transformervej 29, 2730 Herlev, Denmark. Direct +45 31 13 16 10 This public discussion message is non-binding and may contain errors. WiseMo - Remote Service Management for PCs, Phones and Embedded __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Obtaining a TLS session key
How does one obtain the session key from a SSL structure after a successful TLS handshake? I'm planning to implement a TLS connection to do nothing more than authenticated key agreement. Once I've established the connection I plan to somehow extract a AES256 key (from the session key?), which I'll then use in a completely different secure channel, and then drop the connection. I've looked through the docs and forums and asked almighty google, but have so far failed to find out how to extract the master key (session key) from the SSL struct. If I can extract the session key, I still need to extract/derive a AES256 symmetric key from that - any ideas how? Any pointers appreciated... T J __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Obtaining a TLS session key
On Wed, Jan 30, 2013 at 05:29:51PM +1300, T J wrote: How does one obtain the session key from a SSL structure after a successful TLS handshake? You don't, but, you shold instead obtain the tls-unique channel binding data ( https://tools.ietf.org/html/rfc5929#section-3 ) and run the result through a KDF (HKDF should work well) on both ends to obtain a suitable key for a symmetric algorithm of your choice. On the server: /* Support finished MAC of up to 512 bits! */ #define MAX_FINISHED_LEN 64 unsigned char buf[MAX_FINISHED_LEN]; size_t len; if (!SSL_session_reused(s)) len = SSL_get_peer_finished(s, buf, MAX_FINISHED_LEN); else len = SSL_get_finished(s, buf, MAX_FINISHED_LEN); ... Run len bytes of buf through a key-derivation function ... ... the expansion function of HKDF is a reasonable choice. ... On the client: /* Support finished MAC of up to 512 bits! */ #define MAX_FINISHED_LEN 64 unsigned char buf[MAX_FINISHED_LEN]; size_t len; if (!SSL_session_reused(s)) len = SSL_get_finished(s, buf, MAX_FINISHED_LEN); else len = SSL_get_peer_finished(s, buf, MAX_FINISHED_LEN); ... Run len bytes of buf through a key-derivation function ... ... the expansion function of HKDF is a reasonable choice. ... For HKDF see: https://tools.ietf.org/html/rfc5869 -- Viktor. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org