ssl/libcrypto/src/crypto/evp/openbsd_hw.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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@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