FIPS low level blocking for AES, RC4 and Camellia. This is complicated by

use of assembly language routines: rename the assembly language function
to the private_* variant unconditionally and perform tests from a small
C wrapper.
This commit is contained in:
Dr. Stephen Henson 2011-06-05 17:36:44 +00:00
parent 24d7159abd
commit c6fa97a6d6
19 changed files with 171 additions and 62 deletions

View File

@ -190,7 +190,11 @@
#define idea_set_encrypt_key private_idea_set_encrypt_key
#define SEED_set_key private_SEED_set_key
#define RC2_set_key private_RC2_set_key
#define RC4_set_key private_RC4_set_key
#define DES_set_key_unchecked private_DES_set_key_unchecked
#define AES_set_encrypt_key private_AES_set_encrypt_key
#define AES_set_decrypt_key private_AES_set_decrypt_key
#define Camellia_set_key private_Camellia_set_key
#endif
#ifndef HAVE_FORK

View File

@ -90,6 +90,11 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,

View File

@ -625,7 +625,7 @@ static const u32 rcon[] = {
/**
* Expand the cipher key into the encryption key schedule.
*/
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key) {
u32 *rk;
@ -726,7 +726,7 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
/**
* Expand the cipher key into the decryption key schedule.
*/
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key) {
u32 *rk;

View File

@ -50,6 +50,7 @@
*/
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#include <openssl/aes.h>
#include "aes_locl.h"
@ -62,3 +63,23 @@ const char *AES_options(void) {
return "aes(partial)";
#endif
}
/* FIPS wrapper functions to block low level AES calls in FIPS mode */
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key)
{
#ifdef OPENSSL_FIPS
fips_cipher_abort(AES);
#endif
return private_AES_set_encrypt_key(userKey, bits, key);
}
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key)
{
#ifdef OPENSSL_FIPS
fips_cipher_abort(AES);
#endif
return private_AES_set_decrypt_key(userKey, bits, key);
}

View File

@ -39,7 +39,7 @@
# but exhibits up to 10% improvement on other cores.
#
# Second version is "monolithic" replacement for aes_core.c, which in
# addition to AES_[de|en]crypt implements AES_set_[de|en]cryption_key.
# addition to AES_[de|en]crypt implements private_AES_set_[de|en]cryption_key.
# This made it possible to implement little-endian variant of the
# algorithm without modifying the base C code. Motivating factor for
# the undertaken effort was that it appeared that in tight IA-32
@ -2854,12 +2854,12 @@ sub enckey()
&set_label("exit");
&function_end("_x86_AES_set_encrypt_key");
# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
# int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
# AES_KEY *key)
&function_begin_B("AES_set_encrypt_key");
&function_begin_B("private_AES_set_encrypt_key");
&call ("_x86_AES_set_encrypt_key");
&ret ();
&function_end_B("AES_set_encrypt_key");
&function_end_B("private_AES_set_encrypt_key");
sub deckey()
{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
@ -2916,9 +2916,9 @@ sub deckey()
&mov (&DWP(4*$i,$key),$tp1);
}
# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
# int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
# AES_KEY *key)
&function_begin_B("AES_set_decrypt_key");
&function_begin_B("private_AES_set_decrypt_key");
&call ("_x86_AES_set_encrypt_key");
&cmp ("eax",0);
&je (&label("proceed"));
@ -2974,7 +2974,7 @@ sub deckey()
&jb (&label("permute"));
&xor ("eax","eax"); # return success
&function_end("AES_set_decrypt_key");
&function_end("private_AES_set_decrypt_key");
&asciz("AES for x86, CRYPTOGAMS by <appro\@openssl.org>");
&asm_finish();

View File

@ -20,7 +20,7 @@
# May 2007.
#
# AES_set_[en|de]crypt_key is added.
# private_AES_set_[en|de]crypt_key is added.
# July 2010.
#
@ -371,11 +371,11 @@ _armv4_AES_encrypt:
ldr pc,[sp],#4 @ pop and return
.size _armv4_AES_encrypt,.-_armv4_AES_encrypt
.global AES_set_encrypt_key
.type AES_set_encrypt_key,%function
.global private_AES_set_encrypt_key
.type private_AES_set_encrypt_key,%function
.align 5
AES_set_encrypt_key:
sub r3,pc,#8 @ AES_set_encrypt_key
private_AES_set_encrypt_key:
sub r3,pc,#8 @ private_AES_set_encrypt_key
teq r0,#0
moveq r0,#-1
beq .Labrt
@ -392,7 +392,7 @@ AES_set_encrypt_key:
bne .Labrt
.Lok: stmdb sp!,{r4-r12,lr}
sub $tbl,r3,#AES_set_encrypt_key-AES_Te-1024 @ Te4
sub $tbl,r3,#private_AES_set_encrypt_key-AES_Te-1024 @ Te4
mov $rounds,r0 @ inp
mov lr,r1 @ bits
@ -606,21 +606,21 @@ AES_set_encrypt_key:
.Labrt: tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
.size AES_set_encrypt_key,.-AES_set_encrypt_key
.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
.global AES_set_decrypt_key
.type AES_set_decrypt_key,%function
.global private_AES_set_decrypt_key
.type private_AES_set_decrypt_key,%function
.align 5
AES_set_decrypt_key:
private_AES_set_decrypt_key:
str lr,[sp,#-4]! @ push lr
bl AES_set_encrypt_key
bl private_AES_set_encrypt_key
teq r0,#0
ldrne lr,[sp],#4 @ pop lr
bne .Labrt
stmdb sp!,{r4-r12}
ldr $rounds,[r2,#240] @ AES_set_encrypt_key preserves r2,
ldr $rounds,[r2,#240] @ private_AES_set_encrypt_key preserves r2,
mov $key,r2 @ which is AES_KEY *key
mov $i1,r2
add $i2,r2,$rounds,lsl#4
@ -696,7 +696,7 @@ $code.=<<___;
tst lr,#1
moveq pc,lr @ be binary compatible with V4, yet
bx lr @ interoperable with Thumb ISA:-)
.size AES_set_decrypt_key,.-AES_set_decrypt_key
.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
.type AES_Td,%object
.align 5

View File

@ -28,7 +28,7 @@
# May 2007.
#
# Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
# Implement private_AES_set_[en|de]crypt_key. Key schedule setup is avoided
# for 128-bit keys, if hardware support is detected.
# Januray 2009.
@ -730,12 +730,12 @@ _s390x_AES_decrypt:
___
$code.=<<___;
# void AES_set_encrypt_key(const unsigned char *in, int bits,
# void private_AES_set_encrypt_key(const unsigned char *in, int bits,
# AES_KEY *key) {
.globl AES_set_encrypt_key
.type AES_set_encrypt_key,\@function
.globl private_AES_set_encrypt_key
.type private_AES_set_encrypt_key,\@function
.align 16
AES_set_encrypt_key:
private_AES_set_encrypt_key:
lghi $t0,0
clgr $inp,$t0
je .Lminus1
@ -1011,17 +1011,17 @@ $code.=<<___;
.Lminus1:
lghi %r2,-1
br $ra
.size AES_set_encrypt_key,.-AES_set_encrypt_key
.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
# void AES_set_decrypt_key(const unsigned char *in, int bits,
# void private_AES_set_decrypt_key(const unsigned char *in, int bits,
# AES_KEY *key) {
.globl AES_set_decrypt_key
.type AES_set_decrypt_key,\@function
.globl private_AES_set_decrypt_key
.type private_AES_set_decrypt_key,\@function
.align 16
AES_set_decrypt_key:
stg $key,32($sp) # I rely on AES_set_encrypt_key to
private_AES_set_decrypt_key:
stg $key,32($sp) # I rely on private_AES_set_encrypt_key to
stg $ra,112($sp) # save non-volatile registers!
bras $ra,AES_set_encrypt_key
bras $ra,private_AES_set_encrypt_key
lg $key,32($sp)
lg $ra,112($sp)
ltgr %r2,%r2
@ -1123,10 +1123,10 @@ $code.=<<___;
la $key,4($key)
brct $rounds,.Lmix
lmg %r6,%r13,48($sp)# as was saved by AES_set_encrypt_key!
lmg %r6,%r13,48($sp)# as was saved by private_AES_set_encrypt_key!
lghi %r2,0
br $ra
.size AES_set_decrypt_key,.-AES_set_decrypt_key
.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
___
#void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,

View File

@ -1277,13 +1277,13 @@ $code.=<<___;
___
}
# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
# int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
# AES_KEY *key)
$code.=<<___;
.globl AES_set_encrypt_key
.type AES_set_encrypt_key,\@function,3
.globl private_AES_set_encrypt_key
.type private_AES_set_encrypt_key,\@function,3
.align 16
AES_set_encrypt_key:
private_AES_set_encrypt_key:
push %rbx
push %rbp
push %r12 # redundant, but allows to share
@ -1304,7 +1304,7 @@ AES_set_encrypt_key:
add \$56,%rsp
.Lenc_key_epilogue:
ret
.size AES_set_encrypt_key,.-AES_set_encrypt_key
.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
.type _x86_64_AES_set_encrypt_key,\@abi-omnipotent
.align 16
@ -1547,13 +1547,13 @@ $code.=<<___;
___
}
# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
# int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
# AES_KEY *key)
$code.=<<___;
.globl AES_set_decrypt_key
.type AES_set_decrypt_key,\@function,3
.globl private_AES_set_decrypt_key
.type private_AES_set_decrypt_key,\@function,3
.align 16
AES_set_decrypt_key:
private_AES_set_decrypt_key:
push %rbx
push %rbp
push %r12
@ -1622,7 +1622,7 @@ $code.=<<___;
add \$56,%rsp
.Ldec_key_epilogue:
ret
.size AES_set_decrypt_key,.-AES_set_decrypt_key
.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
___
# void AES_cbc_encrypt (const void char *inp, unsigned char *out,

View File

@ -88,6 +88,10 @@ struct camellia_key_st
};
typedef struct camellia_key_st CAMELLIA_KEY;
#ifdef OPENSSL_FIPS
int private_Camellia_set_key(const unsigned char *userKey, const int bits,
CAMELLIA_KEY *key);
#endif
int Camellia_set_key(const unsigned char *userKey, const int bits,
CAMELLIA_KEY *key);

View File

@ -50,6 +50,7 @@
*/
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#include <openssl/camellia.h>
#include "cmll_locl.h"
@ -57,6 +58,14 @@ const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT;
int Camellia_set_key(const unsigned char *userKey, const int bits,
CAMELLIA_KEY *key)
#ifdef OPENSSL_FIPS
{
fips_cipher_abort(Camellia);
return private_Camellia_set_key(userKey, bits, key);
}
int private_Camellia_set_key(const unsigned char *userKey, const int bits,
CAMELLIA_KEY *key)
#endif
{
if(!userKey || !key)
return -1;

View File

@ -62,6 +62,7 @@
#ifndef OPENSSL_NO_RC4
#include <openssl/evp.h>
#include "evp_locl.h"
#include <openssl/objects.h>
#include <openssl/rc4.h>

View File

@ -363,6 +363,8 @@ void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
#define idea_set_encrypt_key private_idea_set_encrypt_key
#define SEED_set_key private_SEED_set_key
#define RC2_set_key private_RC2_set_key
#define RC4_set_key private_RC4_set_key
#define DES_set_key_unchecked private_DES_set_key_unchecked
#define Camellia_set_key private_Camellia_set_key
#endif

View File

@ -21,8 +21,8 @@ TEST=rc4test.c
APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC=rc4_skey.c rc4_enc.c
LIBOBJ=$(RC4_ENC)
LIBSRC=rc4_skey.c rc4_enc.c rc4_utl.c
LIBOBJ=$(RC4_ENC) rc4_utl.o
SRC= $(LIBSRC)

View File

@ -24,7 +24,7 @@
# For reference! This code delivers ~80% of rc4-amd64.pl
# performance on the same Opteron machine.
# (**) This number requires compressed key schedule set up by
# RC4_set_key [see commentary below for further details].
# private_RC4_set_key [see commentary below for further details].
#
# <appro@fy.chalmers.se>
@ -166,8 +166,8 @@ $idx="edx";
&external_label("OPENSSL_ia32cap_P");
# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
&function_begin("RC4_set_key");
# void private_RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
&function_begin("private_RC4_set_key");
&mov ($out,&wparam(0)); # load key
&mov ($idi,&wparam(1)); # load len
&mov ($inp,&wparam(2)); # load data
@ -245,7 +245,7 @@ $idx="edx";
&xor ("eax","eax");
&mov (&DWP(-8,$out),"eax"); # key->x=0;
&mov (&DWP(-4,$out),"eax"); # key->y=0;
&function_end("RC4_set_key");
&function_end("private_RC4_set_key");
# const char *RC4_options(void);
&function_begin_B("RC4_options");

View File

@ -130,7 +130,7 @@ $code.=<<___;
___
}
# void RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp)
# void private_RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp)
{
$cnt="%r0";
$idx="%r1";
@ -143,10 +143,10 @@ $ikey="%r7";
$iinp="%r8";
$code.=<<___;
.globl RC4_set_key
.type RC4_set_key,\@function
.globl private_RC4_set_key
.type private_RC4_set_key,\@function
.align 64
RC4_set_key:
private_RC4_set_key:
stmg %r6,%r8,48($sp)
lhi $cnt,256
la $idx,0(%r0)
@ -182,7 +182,7 @@ RC4_set_key:
.Ldone:
lmg %r6,%r8,48($sp)
br $rp
.size RC4_set_key,.-RC4_set_key
.size private_RC4_set_key,.-private_RC4_set_key
___
}

View File

@ -266,10 +266,10 @@ $ido="%r9";
$code.=<<___;
.extern OPENSSL_ia32cap_P
.globl RC4_set_key
.type RC4_set_key,\@function,3
.globl private_RC4_set_key
.type private_RC4_set_key,\@function,3
.align 16
RC4_set_key:
private_RC4_set_key:
lea 8($dat),$dat
lea ($inp,$len),$inp
neg $len
@ -339,7 +339,7 @@ RC4_set_key:
mov %eax,-8($dat)
mov %eax,-4($dat)
ret
.size RC4_set_key,.-RC4_set_key
.size private_RC4_set_key,.-private_RC4_set_key
.globl RC4_options
.type RC4_options,\@abi-omnipotent

View File

@ -79,6 +79,7 @@ typedef struct rc4_key_st
const char *RC4_options(void);
void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
unsigned char *outdata);

View File

@ -85,7 +85,7 @@ const char *RC4_options(void)
* Date: Wed, 14 Sep 1994 06:35:31 GMT
*/
void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
{
register RC4_INT tmp;
register int id1,id2;

62
crypto/rc4/rc4_utl.c Normal file
View File

@ -0,0 +1,62 @@
/* crypto/rc4/rc4_utl.c -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
* Copyright (c) 2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#include <openssl/rc4.h>
void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
{
#ifdef OPENSSL_FIPS
fips_cipher_abort(RC4);
#endif
private_RC4_set_key(key, len, data);
}