Home | History | Annotate | Download | only in evp
      1 /* Written by Ben Laurie, 2001 */
      2 /*
      3  * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  *
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in
     14  *    the documentation and/or other materials provided with the
     15  *    distribution.
     16  *
     17  * 3. All advertising materials mentioning features or use of this
     18  *    software must display the following acknowledgment:
     19  *    "This product includes software developed by the OpenSSL Project
     20  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
     21  *
     22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     23  *    endorse or promote products derived from this software without
     24  *    prior written permission. For written permission, please contact
     25  *    openssl-core (at) openssl.org.
     26  *
     27  * 5. Products derived from this software may not be called "OpenSSL"
     28  *    nor may "OpenSSL" appear in their names without prior written
     29  *    permission of the OpenSSL Project.
     30  *
     31  * 6. Redistributions of any form whatsoever must retain the following
     32  *    acknowledgment:
     33  *    "This product includes software developed by the OpenSSL Project
     34  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
     35  *
     36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     47  * OF THE POSSIBILITY OF SUCH DAMAGE.
     48  */
     49 
     50 #include <openssl/evp.h>
     51 #include <openssl/objects.h>
     52 #include <openssl/rsa.h>
     53 #include "evp_locl.h"
     54 
     55 /* This stuff should now all be supported through
     56  * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up */
     57 static void *dummy=&dummy;
     58 
     59 #if 0
     60 
     61 /* check flag after OpenSSL headers to ensure make depend works */
     62 #ifdef OPENSSL_OPENBSD_DEV_CRYPTO
     63 
     64 #include <fcntl.h>
     65 #include <stdio.h>
     66 #include <errno.h>
     67 #include <sys/ioctl.h>
     68 #include <crypto/cryptodev.h>
     69 #include <unistd.h>
     70 #include <assert.h>
     71 
     72 /* longest key supported in hardware */
     73 #define MAX_HW_KEY	24
     74 #define MAX_HW_IV	8
     75 
     76 #define MD5_DIGEST_LENGTH	16
     77 #define MD5_CBLOCK		64
     78 
     79 static int fd;
     80 static int dev_failed;
     81 
     82 typedef struct session_op session_op;
     83 
     84 #define CDATA(ctx) EVP_C_DATA(session_op,ctx)
     85 
     86 static void err(const char *str)
     87     {
     88     fprintf(stderr,"%s: errno %d\n",str,errno);
     89     }
     90 
     91 static int dev_crypto_init(session_op *ses)
     92     {
     93     if(dev_failed)
     94 	return 0;
     95     if(!fd)
     96 	{
     97 	int cryptodev_fd;
     98 
     99         if ((cryptodev_fd=open("/dev/crypto",O_RDWR,0)) < 0)
    100 	    {
    101 	    err("/dev/crypto");
    102 	    dev_failed=1;
    103 	    return 0;
    104 	    }
    105         if (ioctl(cryptodev_fd,CRIOGET,&fd) == -1)
    106 	    {
    107 	    err("CRIOGET failed");
    108 	    close(cryptodev_fd);
    109 	    dev_failed=1;
    110 	    return 0;
    111 	    }
    112 	close(cryptodev_fd);
    113 	}
    114     assert(ses);
    115     memset(ses,'\0',sizeof *ses);
    116 
    117     return 1;
    118     }
    119 
    120 static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
    121     {
    122     if(ioctl(fd,CIOCFSESSION,&CDATA(ctx)->ses) == -1)
    123 	err("CIOCFSESSION failed");
    124 
    125     OPENSSL_free(CDATA(ctx)->key);
    126 
    127     return 1;
    128     }
    129 
    130 static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher,
    131 			       const unsigned char *key,int klen)
    132     {
    133     if(!dev_crypto_init(CDATA(ctx)))
    134 	return 0;
    135 
    136     CDATA(ctx)->key=OPENSSL_malloc(MAX_HW_KEY);
    137 
    138     assert(ctx->cipher->iv_len <= MAX_HW_IV);
    139 
    140     memcpy(CDATA(ctx)->key,key,klen);
    141 
    142     CDATA(ctx)->cipher=cipher;
    143     CDATA(ctx)->keylen=klen;
    144 
    145     if (ioctl(fd,CIOCGSESSION,CDATA(ctx)) == -1)
    146 	{
    147 	err("CIOCGSESSION failed");
    148 	return 0;
    149 	}
    150     return 1;
    151     }
    152 
    153 static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
    154 			     const unsigned char *in,unsigned int inl)
    155     {
    156     struct crypt_op cryp;
    157     unsigned char lb[MAX_HW_IV];
    158 
    159     if(!inl)
    160 	return 1;
    161 
    162     assert(CDATA(ctx));
    163     assert(!dev_failed);
    164 
    165     memset(&cryp,'\0',sizeof cryp);
    166     cryp.ses=CDATA(ctx)->ses;
    167     cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
    168     cryp.flags=0;
    169     cryp.len=inl;
    170     assert((inl&(ctx->cipher->block_size-1)) == 0);
    171     cryp.src=(caddr_t)in;
    172     cryp.dst=(caddr_t)out;
    173     cryp.mac=0;
    174     if(ctx->cipher->iv_len)
    175 	cryp.iv=(caddr_t)ctx->iv;
    176 
    177     if(!ctx->encrypt)
    178 	memcpy(lb,&in[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
    179 
    180     if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
    181 	{
    182 	if(errno == EINVAL) /* buffers are misaligned */
    183 	    {
    184 	    unsigned int cinl=0;
    185 	    char *cin=NULL;
    186 	    char *cout=NULL;
    187 
    188 	    /* NB: this can only make cinl != inl with stream ciphers */
    189 	    cinl=(inl+3)/4*4;
    190 
    191 	    if(((unsigned long)in&3) || cinl != inl)
    192 		{
    193 		cin=OPENSSL_malloc(cinl);
    194 		memcpy(cin,in,inl);
    195 		cryp.src=cin;
    196 		}
    197 
    198 	    if(((unsigned long)out&3) || cinl != inl)
    199 		{
    200 		cout=OPENSSL_malloc(cinl);
    201 		cryp.dst=cout;
    202 		}
    203 
    204 	    cryp.len=cinl;
    205 
    206 	    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
    207 		{
    208 		err("CIOCCRYPT(2) failed");
    209 		printf("src=%p dst=%p\n",cryp.src,cryp.dst);
    210 		abort();
    211 		return 0;
    212 		}
    213 
    214 	    if(cout)
    215 		{
    216 		memcpy(out,cout,inl);
    217 		OPENSSL_free(cout);
    218 		}
    219 	    if(cin)
    220 		OPENSSL_free(cin);
    221 	    }
    222 	else
    223 	    {
    224 	    err("CIOCCRYPT failed");
    225 	    abort();
    226 	    return 0;
    227 	    }
    228 	}
    229 
    230     if(ctx->encrypt)
    231 	memcpy(ctx->iv,&out[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
    232     else
    233 	memcpy(ctx->iv,lb,ctx->cipher->iv_len);
    234 
    235     return 1;
    236     }
    237 
    238 static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
    239 					const unsigned char *key,
    240 					const unsigned char *iv, int enc)
    241     { return dev_crypto_init_key(ctx,CRYPTO_3DES_CBC,key,24); }
    242 
    243 #define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher
    244 
    245 BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8,
    246 		     0, dev_crypto_des_ede3_init_key,
    247 		     dev_crypto_cleanup,
    248 		     EVP_CIPHER_set_asn1_iv,
    249 		     EVP_CIPHER_get_asn1_iv,
    250 		     NULL)
    251 
    252 static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx,
    253 					const unsigned char *key,
    254 					const unsigned char *iv, int enc)
    255     { return dev_crypto_init_key(ctx,CRYPTO_ARC4,key,16); }
    256 
    257 static const EVP_CIPHER r4_cipher=
    258     {
    259     NID_rc4,
    260     1,16,0,	/* FIXME: key should be up to 256 bytes */
    261     EVP_CIPH_VARIABLE_LENGTH,
    262     dev_crypto_rc4_init_key,
    263     dev_crypto_cipher,
    264     dev_crypto_cleanup,
    265     sizeof(session_op),
    266     NULL,
    267     NULL,
    268     NULL
    269     };
    270 
    271 const EVP_CIPHER *EVP_dev_crypto_rc4(void)
    272     { return &r4_cipher; }
    273 
    274 typedef struct
    275     {
    276     session_op sess;
    277     char *data;
    278     int len;
    279     unsigned char md[EVP_MAX_MD_SIZE];
    280     } MD_DATA;
    281 
    282 static int dev_crypto_init_digest(MD_DATA *md_data,int mac)
    283     {
    284     if(!dev_crypto_init(&md_data->sess))
    285 	return 0;
    286 
    287     md_data->len=0;
    288     md_data->data=NULL;
    289 
    290     md_data->sess.mac=mac;
    291 
    292     if (ioctl(fd,CIOCGSESSION,&md_data->sess) == -1)
    293 	{
    294 	err("CIOCGSESSION failed");
    295 	return 0;
    296 	}
    297     return 1;
    298     }
    299 
    300 static int dev_crypto_cleanup_digest(MD_DATA *md_data)
    301     {
    302     if (ioctl(fd,CIOCFSESSION,&md_data->sess.ses) == -1)
    303 	{
    304 	err("CIOCFSESSION failed");
    305 	return 0;
    306 	}
    307 
    308     return 1;
    309     }
    310 
    311 /* FIXME: if device can do chained MACs, then don't accumulate */
    312 /* FIXME: move accumulation to the framework */
    313 static int dev_crypto_md5_init(EVP_MD_CTX *ctx)
    314     { return dev_crypto_init_digest(ctx->md_data,CRYPTO_MD5); }
    315 
    316 static int do_digest(int ses,unsigned char *md,const void *data,int len)
    317     {
    318     struct crypt_op cryp;
    319     static unsigned char md5zero[16]=
    320 	{
    321 	0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,
    322 	0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e
    323 	};
    324 
    325     /* some cards can't do zero length */
    326     if(!len)
    327 	{
    328 	memcpy(md,md5zero,16);
    329 	return 1;
    330 	}
    331 
    332     memset(&cryp,'\0',sizeof cryp);
    333     cryp.ses=ses;
    334     cryp.op=COP_ENCRYPT;/* required to do the MAC rather than check it */
    335     cryp.len=len;
    336     cryp.src=(caddr_t)data;
    337     cryp.dst=(caddr_t)data; // FIXME!!!
    338     cryp.mac=(caddr_t)md;
    339 
    340     if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
    341 	{
    342 	if(errno == EINVAL) /* buffer is misaligned */
    343 	    {
    344 	    char *dcopy;
    345 
    346 	    dcopy=OPENSSL_malloc(len);
    347 	    memcpy(dcopy,data,len);
    348 	    cryp.src=dcopy;
    349 	    cryp.dst=cryp.src; // FIXME!!!
    350 
    351 	    if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
    352 		{
    353 		err("CIOCCRYPT(MAC2) failed");
    354 		abort();
    355 		return 0;
    356 		}
    357 	    OPENSSL_free(dcopy);
    358 	    }
    359 	else
    360 	    {
    361 	    err("CIOCCRYPT(MAC) failed");
    362 	    abort();
    363 	    return 0;
    364 	    }
    365 	}
    366     //    printf("done\n");
    367 
    368     return 1;
    369     }
    370 
    371 static int dev_crypto_md5_update(EVP_MD_CTX *ctx,const void *data,
    372 				 unsigned long len)
    373     {
    374     MD_DATA *md_data=ctx->md_data;
    375 
    376     if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
    377 	return do_digest(md_data->sess.ses,md_data->md,data,len);
    378 
    379     md_data->data=OPENSSL_realloc(md_data->data,md_data->len+len);
    380     memcpy(md_data->data+md_data->len,data,len);
    381     md_data->len+=len;
    382 
    383     return 1;
    384     }
    385 
    386 static int dev_crypto_md5_final(EVP_MD_CTX *ctx,unsigned char *md)
    387     {
    388     int ret;
    389     MD_DATA *md_data=ctx->md_data;
    390 
    391     if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
    392 	{
    393 	memcpy(md,md_data->md,MD5_DIGEST_LENGTH);
    394 	ret=1;
    395 	}
    396     else
    397 	{
    398 	ret=do_digest(md_data->sess.ses,md,md_data->data,md_data->len);
    399 	OPENSSL_free(md_data->data);
    400 	md_data->data=NULL;
    401 	md_data->len=0;
    402 	}
    403 
    404     return ret;
    405     }
    406 
    407 static int dev_crypto_md5_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
    408     {
    409     const MD_DATA *from_md=from->md_data;
    410     MD_DATA *to_md=to->md_data;
    411 
    412     // How do we copy sessions?
    413     assert(from->digest->flags&EVP_MD_FLAG_ONESHOT);
    414 
    415     to_md->data=OPENSSL_malloc(from_md->len);
    416     memcpy(to_md->data,from_md->data,from_md->len);
    417 
    418     return 1;
    419     }
    420 
    421 static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx)
    422     {
    423     return dev_crypto_cleanup_digest(ctx->md_data);
    424     }
    425 
    426 static const EVP_MD md5_md=
    427     {
    428     NID_md5,
    429     NID_md5WithRSAEncryption,
    430     MD5_DIGEST_LENGTH,
    431     EVP_MD_FLAG_ONESHOT,	// XXX: set according to device info...
    432     dev_crypto_md5_init,
    433     dev_crypto_md5_update,
    434     dev_crypto_md5_final,
    435     dev_crypto_md5_copy,
    436     dev_crypto_md5_cleanup,
    437     EVP_PKEY_RSA_method,
    438     MD5_CBLOCK,
    439     sizeof(MD_DATA),
    440     };
    441 
    442 const EVP_MD *EVP_dev_crypto_md5(void)
    443     { return &md5_md; }
    444 
    445 #endif
    446 #endif
    447