Re: Obtaining a TLS session key

2013-02-08 Thread Jouni Malinen
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

2013-02-07 Thread Viktor Dukhovni
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

2013-02-07 Thread Thulasi Goriparthi
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

2013-02-07 Thread Jouni Malinen
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

2013-02-07 Thread T J

 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

2013-02-06 Thread T J


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

2013-02-06 Thread Viktor Dukhovni
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

2013-02-06 Thread Trevor Jordan

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

2013-01-31 Thread T J



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

2013-01-31 Thread Viktor Dukhovni
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

2013-01-30 Thread Jakob Bohm

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

2013-01-30 Thread Viktor Dukhovni
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

2013-01-30 Thread Jakob Bohm

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


Re: Obtaining a TLS session key

2013-01-29 Thread Viktor Dukhovni
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