Please tell me about encryption API of OpenSSL 1.0.1

classic Classic list List threaded Threaded
29 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Please tell me about encryption API of OpenSSL 1.0.1

MauMau-2
Hello

I'm new to OpenSSL and this is my first post here. Please let me ask you a
few questions about the symmetric encryption API (EVP_) of OpenSSL 1.0.1.

I'm developing an application which encrypts+writes and reads+decrypts data
to/from files. It has the following requirements (characteristics):

1. The encryption algorithm is AES 256. I'm considering to use CBC block
cipher mode.

2. The application needs to minimize the overhead associated with the
encryption/decryption processing. It utilizes AES-NI (which is offered
transparently by OpenSSL.)

3. It handles two types of files:
3-1 File type 1 consists of 4 KB blocks. The application randomly reads and
writes those blocks.
3-2 File type 2 consists of variable length of records ranging from several
bytes to a few kilobytes. The application randomly reads and writes those
records.
Here, "randomly" means that the application needs to be able to read and
decrypt one arbitrary block/record without any preceding blocks/records.


Q1: Is AES-NI automatically utilized on the processors that have the
capability? Do I have to do anything (e.g. specify some engine in
openssl.conf)?

Q2: I'm going to call EVP_CIPHER_CTX_set_padding(&ctx, 0) for file type 1.
Can I omit the calls to EVP_EncryptFinal_ex/EVP_DecryptFinal_ex between
EVP_EncryptUpdate/EVP_DecryptUpdate calls? I want to avoid function calls as
much as possible.

Q3: Is it allowed to specify the same buffer (address) for in and out
arguments in calls to EVP_EncryptUpdate/EVP_DecryptUpdate? Some places in
OpenSSL does that like "EVP_EncryptUpdate(&ctx, data, &outlen, data,
inlen)", but that usage is not specified in the evp manual page.

Q4: Do I have to call EVP_EncryptInit_ex/EVP_DecryptInit_ex for each
block/record? I'm concerned about the overhead of those functions. For
example, I want to make function calls as follows. However, this does not
seem to work.

 /* one-time initialization */
 ERR_load_crypto_strings();
 OpenSSL_add_all_algorithms();
 EVP_CIPHER_CTX_init(&enc_ctx);
 EVP_CIPHER_CTX_init(&dec_ctx);
 EVP_EncryptInit_ex(&enc_ctx, EVP_aes_256_cbc(), NULL, key, iv);
 EVP_CIPHER_CTX_set_padding(&enc_ctx, 0);
 EVP_DecryptInit_ex(&dec_ctx, EVP_aes_256_cbc(), NULL, key, iv);
 EVP_CIPHER_CTX_set_padding(&dec_ctx, 0);

 /* encrypt first block */
 EVP_EncryptUpdate(&enc_ctx, block1, &outlen, block1, 4096);
 /* encrypt second block */
 EVP_EncryptUpdate(&enc_ctx, block2, &outlen, block2, 4096);

 /* decrypt second block */
 EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
 /* decrypt first block */
 EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);

The above code produces wrong data for block2. One of the following seems to
fix this problem. But is there any way to use CBC without repeated calls to
EVP_EncryptInit_ex/EVP_DecryptInit_ex?

1. Call EVP_EncryptInit_ex/EVP_DecryptInit_ex before each
EVP_EncryptUpdate/EVP_DecryptUpdate.
2. Replace EVP_aes_256_cbc() with EVP_aes_256_ecb().

Regards
MauMau

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

Thomas BERNARD-3

/* one-time initialization */
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
EVP_CIPHER_CTX_init(&enc_ctx);
EVP_CIPHER_CTX_init(&dec_ctx);
EVP_EncryptInit_ex(&enc_ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&enc_ctx, 0);
EVP_DecryptInit_ex(&dec_ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&dec_ctx, 0);

/* encrypt first block */
EVP_EncryptUpdate(&enc_ctx, block1, &outlen, block1, 4096);
/* encrypt second block */
EVP_EncryptUpdate(&enc_ctx, block2, &outlen, block2, 4096);

/* decrypt second block */
EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
/* decrypt first block */
EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);

The above code produces wrong data for block2. One of the following seems to fix this problem. But is there any way to use CBC without repeated calls to EVP_EncryptInit_ex/EVP_DecryptInit_ex?

1. Call EVP_EncryptInit_ex/EVP_DecryptInit_ex before each EVP_EncryptUpdate/EVP_DecryptUpdate.
2. Replace EVP_aes_256_cbc() with EVP_aes_256_ecb().

To my understanding :
With ECB, the order in which the blocks are crypted/decrypted doesn't matter.
With CBC and most block modes, it DOES matter !
So if block 1 is encrypted first it MUST be decrypted first.

/* decrypt second block */
EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
/* decrypt first block */
EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);
is WRONG

EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);
EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
should work better

Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

Dr. Stephen Henson
In reply to this post by MauMau-2
On Mon, Apr 16, 2012, MauMau wrote:

> Hello
>
> Q1: Is AES-NI automatically utilized on the processors that have the
> capability? Do I have to do anything (e.g. specify some engine in
> openssl.conf)?
>

In OpenSSL 1.0.1 it is automatically supported provided you use the EVP
interface, you don't need to do anything else.

> Q2: I'm going to call EVP_CIPHER_CTX_set_padding(&ctx, 0) for file
> type 1. Can I omit the calls to
> EVP_EncryptFinal_ex/EVP_DecryptFinal_ex between
> EVP_EncryptUpdate/EVP_DecryptUpdate calls? I want to avoid function
> calls as much as possible.
>

You can yes, those calls just check for a multiple of the block length.

> Q3: Is it allowed to specify the same buffer (address) for in and
> out arguments in calls to EVP_EncryptUpdate/EVP_DecryptUpdate? Some
> places in OpenSSL does that like "EVP_EncryptUpdate(&ctx, data,
> &outlen, data, inlen)", but that usage is not specified in the evp
> manual page.
>

That is specifically allowed for ciphers yes.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

MauMau-2
Hello, Stephen, Thomas,

From: "Thomas BERNARD" <[hidden email]>

> To my understanding :
> With ECB, the order in which the blocks are crypted/decrypted doesn't
> matter.
> With CBC and most block modes, it DOES matter !
> So if block 1 is encrypted first it MUST be decrypted first.
>
> /* decrypt second block */
> EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
> /* decrypt first block */
> EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);
> is WRONG
>
> EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);
> EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
> should work better

Thank you very much for your quick responses. I'm glad about the answers to
Q1-Q3 as I can easily minimize the overhead in encryption/decryption.

As for Q4, yes, decrypting blocks in the same order as encrypting them
certainly produced correct data.  owever, I cannot do that because the
application needs to encrypt/decrypt blocks/records in random order.

In addition, I feel I'd better use CBC rather than ECB at least for file
type 1 (collection of 4KB blocks), so that others don't know the pattern of
blocks such as "this 4KB block consists of the same 16-byte sequences." On
the other hand, it is okay for others to know "this and that 4KB blocks have
identical data" or "this and that records are identical." (is this thinking
reasonable in cryptography world?)

However, I'd like to avoid the overhead of calling
EVP_EncryptInit_ex/EVP_DecryptInit_ex for each block/record, because I
wonder if those functions have relatively high overhead especially when
AES-NI decrease the overhead of encryption/decryption. That is, I'm afraid
that repeated init calls reduces the benefits gained by AES-NI. Is there any
way?

  if (ctx->cipher->ctx_size)
   {
   ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
...
   case EVP_CIPH_CBC_MODE:

   OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
     (int)sizeof(ctx->iv));
   if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
   memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
   break;
...
 if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
  if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
 }

Regards
MauMau

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: Please tell me about encryption API of OpenSSL 1.0.1

Edward Ned Harvey (openssl)
In reply to this post by MauMau-2
> From: Edward Ned Harvey
>
> I can't think of anything wrong with using the block number as the
> IV, and then use ECB.

Oh yeah.  I can think of something wrong with that.  If an attacker knows
the block number, and they have some intelligent guess about the plaintext,
then they might be able to confirm their guess easily.  This will certainly
happen rather frequently in files that have large sequences of zeros, or
other predictable patterns.

If you want to be able to do random access...  

Take it as given you have some plaintext, and you have a key, and you know
your context (you know what block number you're working on.)  An attacker
will also know what block number you're working on.  The only things the
attacker doesn't know is your key and your plaintext.  There is only one
solution.  You must use a second key.  Use your first key to encrypt the
second key (so an attacker can hopefully never know either one of your
keys.)  Use your second key combined with the block number (I suggest
encrypting or hashing the block number using the second key, but simple AND
or XOR should also be fine) and use the resultant data as the IV for your
actual encryption operation.  

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: Please tell me about encryption API of OpenSSL 1.0.1

Edward Ned Harvey (openssl)
> From: [hidden email] [mailto:owner-openssl-
> [hidden email]] On Behalf Of Edward Ned Harvey
>
> attacker doesn't know is your key and your plaintext.  There is only one
> solution.  You must use a second key.  Use your first key to encrypt the
> second key (so an attacker can hopefully never know either one of your
> keys.)  Use your second key combined with the block number (I suggest
> encrypting or hashing the block number using the second key, but simple
> AND
> or XOR should also be fine) and use the resultant data as the IV for your
> actual encryption operation.

I don't see any reason why the second key couldn't match the first.  You
could simply encrypt the block number, and use the result as the IV when you
encrypt your actual data block, using ECB.  This is effectively
reimplementing CBC, where you don't make individual blocks dependent on each
other - instead you make each individual block dependent only on its block
number, where you're using the block number as the preceding block of data,
and the *only* preceding block of data.  Every block number is guaranteed
unique and independent, so you're able to do random access, and since there
are never any repeats, there will never be any repeated cipherblocks, even
if there is repeated plaintext.

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

Jakob Bohm-7
On 4/17/2012 1:59 PM, Edward Ned Harvey wrote:

>> From: [hidden email] [mailto:owner-openssl-
>> [hidden email]] On Behalf Of Edward Ned Harvey
>>
>> attacker doesn't know is your key and your plaintext.  There is only one
>> solution.  You must use a second key.  Use your first key to encrypt the
>> second key (so an attacker can hopefully never know either one of your
>> keys.)  Use your second key combined with the block number (I suggest
>> encrypting or hashing the block number using the second key, but simple
>> AND
>> or XOR should also be fine) and use the resultant data as the IV for your
>> actual encryption operation.
> I don't see any reason why the second key couldn't match the first.  You
> could simply encrypt the block number, and use the result as the IV when you
> encrypt your actual data block, using ECB.  This is effectively
> reimplementing CBC, where you don't make individual blocks dependent on each
> other - instead you make each individual block dependent only on its block
> number, where you're using the block number as the preceding block of data,
> and the *only* preceding block of data.  Every block number is guaranteed
> unique and independent, so you're able to do random access, and since there
> are never any repeats, there will never be any repeated cipherblocks, even
> if there is repeated plaintext.
Note: I think there is a misunderstanding of the word "block" here.
The OP refers to data blocks of about 4Kbyte, you refer to the
individual AES blocks of 16 bytes each.

As for using the main key to generate IVs from block numbers, an
expert once confirmed to me that the following should be safe:

Set CBC-IV=AESrawFunc(key, block number).

I think (not sure at this moment) this is the same as

Set CBC-IV=CBC-AES(key, 0, block number)  // Second arg is IV

Which for encrypt (but not decrypt) I think is the same as

Set encrypted=ThrowAwayFirst16Bytes(CBC-AES, 0, Concat(block
number-as-16-bytes, 4K data block))

Decrypt will need to do the two steps separately.

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 List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

Ken Goldman-2
In reply to this post by MauMau-2
The standard answer:  If this is a real security project, hire an
expert.  If you design your own crypto algorithm, you will get it wrong.

If this is just for fun, to learn about openssl, CTR mode will give you
random access.

On 4/16/2012 6:41 PM, MauMau wrote:
>
> As for Q4, yes, decrypting blocks in the same order as encrypting them
> certainly produced correct data. owever, I cannot do that because the
> application needs to encrypt/decrypt blocks/records in random order.


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

MauMau-2
Hello, Edward, Jakob, Ken,

Thanks for lots of ideas and information. I'll investigate Edward's
block-number-based iv and Ken's CTR mode. Let me consult you if I get stuck
again. I'll consider some way to eliminate the need to call
EVP_EncryptInit_ex/EVP_DecryptInit_ex for each block/record.

Regards
MauMau

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Selecting certificate to be presented by a given endpoint in establishing an ssl connection

Nou Dadoun
In reply to this post by Jakob Bohm-7
Quick question regarding certificate usage in an ssl connection; you can associate a number of certificates with a server endpoint - is there any way of deciding at runtime which certificate is presented to the client (depending on the identity of the client say).

And would the same mechanism be usable for the certificate the client presents in the case of mutual authentication?

(Pointers to documentation if any would be sufficient!)

Thanks .... N

---
Nou Dadoun
[hidden email]
604-628-1215
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

Matt Caswell (frodo@baggins.org)
In reply to this post by MauMau-2
On 17/04/12 15:31, MauMau wrote:

> Hello, Edward, Jakob, Ken,
>
> Thanks for lots of ideas and information. I'll investigate Edward's
> block-number-based iv and Ken's CTR mode. Let me consult you if I get
> stuck again. I'll consider some way to eliminate the need to call
> EVP_EncryptInit_ex/EVP_DecryptInit_ex for each block/record.
>
> Regards
> MauMau
>
I would second Ken's recommendation for CTR mode for random access if
the random access is for *read* only.

If you are going to try and use CBC mode for random (read) access then
the IV must be set to the last 16 bytes of the immediately preceding 4k
record...or the initial IV if it is the first 4k record. This is why in
your example code you got wrong data for block2.

However in your original post you said "File type 1 consists of 4 KB
blocks. The application randomly reads and writes those blocks. ". If
you are going to attempt to randomly change, write and re-encrypt a
record in the middle of your file then this will absolutely not work in
CBC mode. You will corrupt everything in your file beyond the write
because as noted above the last 16 bytes of the record you have just
written is the IV for the next record. As you have changed the last 16
bytes by reencrypting you will not be able to decrypt the following record.

If you attempt to use CTR mode in random read/write mode then this will
open a massive security hole in your application. In CTR mode the
counter is initialised to a random value and then incremented for each
16 byte block. The encryption works by encrypting the counter and
xor'ing it to the plaintext. So if the plaintext for block 7 is m7, then
the ciphertext, c7, is calculated as follows:
c7 = AES(ctr + 7) xor m7

Now if you modify m7 to be m7' then c7' would be:
c7' = AEX(ctr +7) xor m7'

The problem is that an attacker can xor the two ciphertexts together as
follows:
c7 xor c7' = AES(ctr + 7) xor AEX(ctr + 7) xor m7 xor m7' = m7 xor m7'
In other words xoring the original block 7 with the modified block 7
will be equal to the two plaintexts xored together....which is trivial
to crack.

If I have interpreted your original post correctly and you are trying to
do random read/write then you need to select a mode that supports it.
(Maybe XTS??? I'm not familiar with the details of this but probably
worth looking at).


Matt





______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: Please tell me about encryption API of OpenSSL 1.0.1

Edward Ned Harvey (openssl)
In reply to this post by Ken Goldman-2
> From: [hidden email] [mailto:owner-openssl-
> [hidden email]] On Behalf Of Ken Goldman
>
> The standard answer:  If this is a real security project, hire an
> expert.  If you design your own crypto algorithm, you will get it wrong.
>
> If this is just for fun, to learn about openssl, CTR mode will give you
> random access.

The thing about CTR mode is that it needs a nonce.  Good when you're
engaging live communication with another party, so you can do the nonce
exchange like a key exchange, but if the encrypted data is on disk for a
later time...  You need some way of regenerating the nonce.  Which is
conceptually the same thing as I originally said ... Store a second key,
encrypted... Then decrypt the second key and apply it to the block number
and using the result for IV.  When I say "apply" to the block number, I
suggested Adding or Xoring or encrypting...  In CTR mode, you're basically
adding the nonce & the counter, using it as the IV.

So, in consideration of the two techniques:  Storing an encrypted second key
(or nonce) and adding or xor'ing with block number to generate IV (such as
CTR mode), versus encrypting the block number with your original key to use
for IV...

If you store a second key (or nonce) separately, then you can decrypt the
second key once, and repeatedly perform a really fast cheap operation such
as add.  (Such as CTR mode does.)

If you directly encrypt the block number, then you don't need to store a
second key, but you have to perform twice as many encryption/decryption
operations, because you'll have to encrypt the block number once for every
block, before you can encrypt/decrypt your data.

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: Please tell me about encryption API of OpenSSL 1.0.1

Edward Ned Harvey (openssl)
In reply to this post by Ken Goldman-2
> From: [hidden email] [mailto:owner-openssl-
> [hidden email]] On Behalf Of Ken Goldman
>
> The standard answer:  If this is a real security project, hire an
> expert.  If you design your own crypto algorithm, you will get it wrong.

Or, if you're pretty confident you know how a block cipher works, you can
create a solution (which is not the same as designing your own crypto
algorithm) and then for the sake of diligence, hire an expert to review.
Probably much cheaper this way.

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

Jeffrey Walton-3
In reply to this post by Edward Ned Harvey (openssl)
On Tue, Apr 17, 2012 at 7:59 AM, Edward Ned Harvey
<[hidden email]> wrote:

>> From: [hidden email] [mailto:owner-openssl-
>> [hidden email]] On Behalf Of Edward Ned Harvey
>>
>> attacker doesn't know is your key and your plaintext.  There is only one
>> solution.  You must use a second key.  Use your first key to encrypt the
>> second key (so an attacker can hopefully never know either one of your
>> keys.)  Use your second key combined with the block number (I suggest
>> encrypting or hashing the block number using the second key, but simple
>> AND
>> or XOR should also be fine) and use the resultant data as the IV for your
>> actual encryption operation.
>
> I don't see any reason why the second key couldn't match the first.  You
> could simply encrypt the block number, and use the result as the IV when you
> encrypt your actual data block, using ECB.  This is effectively
> reimplementing CBC, where you don't make individual blocks dependent on each
> other - instead you make each individual block dependent only on its block
> number, where you're using the block number as the preceding block of data,
> and the *only* preceding block of data.
Sounds more like counter mode to me.

> Every block number is guaranteed
> unique and independent, so you're able to do random access, and since there
> are never any repeats, there will never be any repeated cipherblocks, even
> if there is repeated plaintext.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

Jeffrey Walton-3
In reply to this post by Edward Ned Harvey (openssl)
On Tue, Apr 17, 2012 at 9:47 PM, Edward Ned Harvey
<[hidden email]> wrote:

>> From: [hidden email] [mailto:owner-openssl-
>> [hidden email]] On Behalf Of Ken Goldman
>>
>> The standard answer:  If this is a real security project, hire an
>> expert.  If you design your own crypto algorithm, you will get it wrong.
>>
>> If this is just for fun, to learn about openssl, CTR mode will give you
>> random access.
>
> The thing about CTR mode is that it needs a nonce.
NIST 800-38A approves two ways to use counter mode. See Appendix B for
guidance on choosing the initial value and the increment function.

Jeff
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Selecting certificate to be presented by a given endpoint in establishing an ssl connection

Jakob Bohm-7
In reply to this post by Nou Dadoun
On 4/17/2012 7:00 PM, Nou Dadoun wrote:
> Quick question regarding certificate usage in an ssl connection; you can associate a number of certificates with a server endpoint - is there any way of deciding at runtime which certificate is presented to the client (depending on the identity of the client say).
Unfortunately not (almost, read on).

This has been a major problem for the top use of SSL/TLS:
https web servers.

Currently the two most common workarounds are either:

A. Assign a separate IP address or port to each certificate
   (costly given the worldwide shortage of IPv4 addresses and
   the "default firewall configuration" induced shortage of
   usable TCP ports).

B. Generate a certificate which covers all the desired
   identities, either via wildcards or SubjectAlternativeNames.

However recent TLS versions have introduced a new mechanism
where the client can tell the server which name it wants a
certificate for.  This is still not widely available in
web browsers and other stock clients, but that should improve
over time.
> And would the same mechanism be usable for the certificate the client presents in the case of mutual authentication?
For client certificates, there is a standard mechanism, going
back at least to SSL 3, maybe even to SSL 2: The server tells
the client if it wants mutual authentication and identifies
the acceptable certificates by a list of CAs.  Clients
routinely use this to select the appropriate certificate.
>
> (Pointers to documentation if any would be sufficient!)
>
> Thanks .... N
>
>

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 List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: Please tell me about encryption API of OpenSSL 1.0.1

Edward Ned Harvey (openssl)
In reply to this post by Jeffrey Walton-3
> From: [hidden email] [mailto:owner-openssl-
> [hidden email]] On Behalf Of Jeffrey Walton
>
> On Tue, Apr 17, 2012 at 9:47 PM, Edward Ned Harvey
> <[hidden email]> wrote:
> >> From: [hidden email] [mailto:owner-openssl-
> >> [hidden email]] On Behalf Of Ken Goldman
> >>
> >> The standard answer:  If this is a real security project, hire an
> >> expert.  If you design your own crypto algorithm, you will get it wrong.
> >>
> >> If this is just for fun, to learn about openssl, CTR mode will give you
> >> random access.
> >
> > The thing about CTR mode is that it needs a nonce.
> NIST 800-38A approves two ways to use counter mode. See Appendix B for
> guidance on choosing the initial value and the increment function.

I think what you're saying is that it doesn't necessarily need to be a nonce, and it doesn't necessarily need to be a increment (++), as long as you have any method for ensuring uniqueness and generating sequentially unique counter blocks across all messages.  Right?  Or have I missed the point?

This seems to affirm what I said - If you're using CTR mode, you'll need to store something (be it a second key, or a nonce, or something functionally equivalent) encrypted along with your encrypted data.  Whatever you choose as your incrementing function is irrelevant, as long as it satisifes the conditions of being sequentially repeatable, and always unique.   ...   If you're doing something like my other suggestion - encrypting the block number and then using the result as the IV - it satisfies all the requirements described in Appendix B, where m=128 (in other words, you have no nonce, and you're using all the bits for incrementing function.)  There's an important restriction there - Presumably Maumau would want to encrypt more than one file.  He'll either need to treat all the blocks of all the files as sequential blocks, or choose a different key for each file.

It seems, no matter how you cut it, you'll need a different key (or nonce or something unique) for each file.

Furthermore, as Matt said, it works fine if you write once and read many times.  But if you want to write a block, then change it, then change it back to what it used to be...  Given the same key, plaintext, and IV, the block cipher will produce the same output.  So an attacker could know you changed it, and then put it back.  Maybe you don't care about that, but ideally you would have a way of keeping track of a new key/nonce/whatever ...

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: Selecting certificate to be presented by a given endpoint in establishing an ssl connection

Dave Thompson-5
In reply to this post by Jakob Bohm-7
> From: [hidden email] On Behalf Of Jakob Bohm
> Sent: Wednesday, 18 April, 2012 07:57

> On 4/17/2012 7:00 PM, Nou Dadoun wrote:
> > Quick question regarding certificate usage in an ssl
> connection; you can associate a number of certificates with a
> server endpoint - is there any way of deciding at runtime
> which certificate is presented to the client (depending on
> the identity of the client say).

> Unfortunately not (almost, read on).
>
> This has been a major problem for the top use of SSL/TLS:
> https web servers.
>
> Currently the two most common workarounds are either:
>
> A. Assign a separate IP address or port to each certificate
>    (costly given the worldwide shortage of IPv4 addresses and
>    the "default firewall configuration" induced shortage of
>    usable TCP ports).
>
yes.

> B. Generate a certificate which covers all the desired
>    identities, either via wildcards or SubjectAlternativeNames.
>
and map multiple DNS names to same IP address, yes.

> However recent TLS versions have introduced a new mechanism
> where the client can tell the server which name it wants a
> certificate for.  This is still not widely available in
> web browsers and other stock clients, but that should improve
> over time.

Called Server Name Indication, abbreviated SNI.

But note SNI or address/port selects server cert based on
the server *chosen* by the client -- not client *identity*
as the OP halfheartedly requested. If you want to select
based on the client, you must do it indirectly by having
different clients/groups use different server 'faces',
maybe by giving them different URLs/links to click.


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

Jeffrey Walton-3
In reply to this post by Edward Ned Harvey (openssl)
On Wed, Apr 18, 2012 at 9:04 AM, Edward Ned Harvey
<[hidden email]> wrote:

>> From: [hidden email] [mailto:owner-openssl-
>> [hidden email]] On Behalf Of Jeffrey Walton
>>
>> On Tue, Apr 17, 2012 at 9:47 PM, Edward Ned Harvey
>> <[hidden email]> wrote:
>> >> From: [hidden email] [mailto:owner-openssl-
>> >> [hidden email]] On Behalf Of Ken Goldman
>> >>
>> >> The standard answer:  If this is a real security project, hire an
>> >> expert.  If you design your own crypto algorithm, you will get it wrong.
>> >>
>> >> If this is just for fun, to learn about openssl, CTR mode will give you
>> >> random access.
>> >
>> > The thing about CTR mode is that it needs a nonce.
>> NIST 800-38A approves two ways to use counter mode. See Appendix B for
>> guidance on choosing the initial value and the increment function.
>
> I think what you're saying is that it doesn't necessarily need to be a nonce, and it doesn't necessarily need to be a increment (++), as long as you have any method for ensuring uniqueness and generating sequentially unique counter blocks across all messages.  Right?  Or have I missed the point?
>
> This seems to affirm what I said - If you're using CTR mode, you'll need to store something (be it a second key, or a nonce, or something functionally equivalent) encrypted along with your encrypted data.  Whatever you choose as your incrementing function is irrelevant, as long as it satisifes the conditions of being sequentially repeatable, and always unique.   ...   If you're doing something like my other suggestion - encrypting the block number and then using the result as the IV - it satisfies all the requirements described in Appendix B, where m=128 (in other words, you have no nonce, and you're using all the bits for incrementing function.)  There's an important restriction there - Presumably Maumau would want to encrypt more than one file.  He'll either need to treat all the blocks of all the files as sequential blocks, or choose a different key for each file.
>
> It seems, no matter how you cut it, you'll need a different key (or nonce or something unique) for each file.
>
> Furthermore, as Matt said, it works fine if you write once and read many times.  But if you want to write a block, then change it, then change it back to what it used to be...  Given the same key, plaintext, and IV, the block cipher will produce the same output.  So an attacker could know you changed it, and then put it back.  Maybe you don't care about that, but ideally you would have a way of keeping track of a new key/nonce/whatever ...
Encryption alone is usually not enough. You should be able to detect
copy/paste attacks with an authenticator.
http://www.codeproject.com/Articles/34380/Authenticated-Encryption.

Disk blocks are kind of unique in that you usually can't tolerate the
authentication tag. See "AES-CBC + Elephant diffuser: A Disk
Encryption Algorithm for Windows Vista" by Niels Furgeson and the way
Microsoft attempted to solve it using Poor Man's Authentication.
http://download.microsoft.com/download/0/2/3/0238acaf-d3bf-4a6d-b3d6-0a0be4bbb36e/BitLockerCipher200608.pdf.

Jeff
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Please tell me about encryption API of OpenSSL 1.0.1

MauMau-2
Hello,


Thanks a lot for your valuable advice. I'm looking into the CBC with IVs
based on block numbers, CTR, and XTS. I'm refering to the pages below:

Block cipher modes of operation
http://en.wikipedia.org/wiki/Block_cipher_mode

Disk encryption theory
http://en.wikipedia.org/wiki/Disk_encryption_theory

I'll continue the investigation a little more.

Apart from that, let me go back to my original question 4 in my first mail.

----------------------------------------
Q4: Do I have to call EVP_EncryptInit_ex/EVP_DecryptInit_ex for each
block/record? I'm concerned about the overhead of those functions. For
example, I want to make function calls as follows. However, this does not
seem to work.

 /* one-time initialization */
 ERR_load_crypto_strings();
 OpenSSL_add_all_algorithms();
 EVP_CIPHER_CTX_init(&enc_ctx);
 EVP_CIPHER_CTX_init(&dec_ctx);
 EVP_EncryptInit_ex(&enc_ctx, EVP_aes_256_cbc(), NULL, key, iv);
 EVP_CIPHER_CTX_set_padding(&enc_ctx, 0);
 EVP_DecryptInit_ex(&dec_ctx, EVP_aes_256_cbc(), NULL, key, iv);
 EVP_CIPHER_CTX_set_padding(&dec_ctx, 0);

 /* encrypt first block */
 EVP_EncryptUpdate(&enc_ctx, block1, &outlen, block1, 4096);
 /* encrypt second block */
 EVP_EncryptUpdate(&enc_ctx, block2, &outlen, block2, 4096);

 /* decrypt second block */
 EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
 /* decrypt first block */
 EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);

The above code produces wrong data for block2. ...
----------------------------------------


I said I'm afraid of the overhead of EVP_EncryptInit_ex/EVP_DecryptInit_ex
calls. Then, I looked through the source code of those functions and knew
that my concern seems correct.

If I call those functions specifying the same cipher, key and IV as the
previous call, those functions call EVP_CIPHER_CTX_cleanup to clean up the
cipher context, re-allocate some memory for the cipher context, and performs
key and IV initialization. Those processing may be too much for each
block/record encryption/decryption.

According to the source code, I think I can pass NULL for cipher, key and IV
to use those specified in the previous call, eliminating most of the
processing overhead. Is this usage correct? The following code worked
successfully, producing the correct data:

----------------------------------------
 /* one-time initialization */
 ERR_load_crypto_strings();
 OpenSSL_add_all_algorithms();
 EVP_CIPHER_CTX_init(&enc_ctx);
 EVP_CIPHER_CTX_init(&dec_ctx);
 EVP_EncryptInit_ex(&enc_ctx, EVP_aes_256_cbc(), NULL, key, iv);
 EVP_CIPHER_CTX_set_padding(&enc_ctx, 0);
 EVP_DecryptInit_ex(&dec_ctx, EVP_aes_256_cbc(), NULL, key, iv);
 EVP_CIPHER_CTX_set_padding(&dec_ctx, 0);

 /* encrypt first block */
 EVP_EncryptUpdate(&enc_ctx, block1, &outlen, block1, 4096);
 /* encrypt second block */
 EVP_EncryptInit_ex(&enc_ctx, NULL, NULL, NULL, NULL);
 EVP_EncryptUpdate(&enc_ctx, block2, &outlen, block2, 4096);

 /* decrypt second block */
 EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096);
 /* decrypt first block */
 EVP_DecryptInit_ex(&dec_ctx, NULL, NULL, NULL, NULL);
 EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096);
----------------------------------------


Regards
MauMau

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
12