Commit 82b22305 authored by Ben Laurie's avatar Ben Laurie
Browse files

Add RC4 support to OpenBSD.

parent a8a00498
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@
static void load_ciphers(ENGINE *e)
    {
    ENGINE_add_cipher(e,EVP_dev_crypto_des_ede3_cbc());
    ENGINE_add_cipher(e,EVP_dev_crypto_rc4());
    }

ENGINE *ENGINE_openbsd_dev_crypto(void)
+1 −0
Original line number Diff line number Diff line
@@ -558,6 +558,7 @@ const EVP_CIPHER *EVP_des_ede3_cbc(void);
const EVP_CIPHER *EVP_desx_cbc(void);
# ifdef OPENSSL_OPENBSD_DEV_CRYPTO
const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
const EVP_CIPHER *EVP_dev_crypto_rc4(void);
# endif
#endif
#ifndef OPENSSL_NO_RC4
+6 −0
Original line number Diff line number Diff line
@@ -222,6 +222,7 @@ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
	b=ctx->cipher->block_size;
	if (b == 1)
		{
		EVP_CIPHER_CTX_cleanup(ctx);
		*outl=0;
		return 1;
		}
@@ -303,6 +304,7 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
	b=ctx->cipher->block_size;
	if (ctx->flags & EVP_CIPH_NO_PADDING)
		{
		EVP_CIPHER_CTX_cleanup(ctx);
		if(ctx->buf_len)
			{
			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
@@ -315,12 +317,14 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
		{
		if (ctx->buf_len || !ctx->final_used)
			{
			EVP_CIPHER_CTX_cleanup(ctx);
			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
			return(0);
			}
		n=ctx->final[b-1];
		if (n > b)
			{
			EVP_CIPHER_CTX_cleanup(ctx);
			EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
			return(0);
			}
@@ -328,6 +332,7 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
			{
			if (ctx->final[--b] != n)
				{
				EVP_CIPHER_CTX_cleanup(ctx);
				EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_BAD_DECRYPT);
				return(0);
				}
@@ -339,6 +344,7 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
		}
	else
		*outl=0;
	EVP_CIPHER_CTX_cleanup(ctx);
	return(1);
	}

+52 −28
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@

/* longest key supported in hardware */
#define MAX_HW_KEY	24
#define MAX_HW_IV	8

static int fd;
static int dev_failed;
@@ -107,6 +108,7 @@ static int dev_crypto_init(EVP_CIPHER_CTX *ctx)

static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
    {
    printf("Cleanup %d\n",data(ctx)->ses);
    if(ioctl(fd,CIOCFSESSION,&data(ctx)->ses) == -1)
	err("CIOCFSESSION failed");

@@ -116,40 +118,34 @@ static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
    }

/* FIXME: there should be some non-fatal way to report we fell back to s/w? */
static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
					const unsigned char *key,
					const unsigned char *iv, int enc)
static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher,
			       const unsigned char *key,int klen)
    {
    if(!dev_crypto_init(ctx))
	{
	/* fall back to using software... */
	ctx->cipher=EVP_des_ede3_cbc();
	return ctx->cipher->init(ctx,key,iv,enc);
	}
    memcpy(data(ctx)->key,key,24);
	return 0;

    data(ctx)->cipher=CRYPTO_3DES_CBC;
    assert(ctx->cipher->iv_len <= MAX_HW_IV);

    memcpy(data(ctx)->key,key,klen);
    
    data(ctx)->cipher=cipher;
    data(ctx)->mac=0;
    data(ctx)->keylen=24;
    data(ctx)->keylen=klen;

    if (ioctl(fd,CIOCGSESSION,data(ctx)) == -1)
	{
	err("CIOCGSESSION failed");
	/* fall back to using software... */
	dev_crypto_cleanup(ctx);
	ctx->cipher=EVP_des_ede3_cbc();
	return ctx->cipher->init(ctx,key,iv,enc);
	return 0;
	}
    printf("Init %d\n",data(ctx)->ses);
    return 1;
    }

static int dev_crypto_des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, 
					  unsigned char *out,
					  const unsigned char *in,
					  unsigned int inl)
static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
			     const unsigned char *in,unsigned int inl)
    {
    struct crypt_op cryp;
    unsigned char lb[8];
    unsigned char lb[MAX_HW_IV];

    assert(data(ctx));
    assert(!dev_failed);
@@ -158,18 +154,16 @@ static int dev_crypto_des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx,
    cryp.ses=data(ctx)->ses;
    cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
    cryp.flags=0;
#if 0
    cryp.len=((inl+7)/8)*8;
#endif
    cryp.len=inl;
    assert((inl&7) == 0);
    assert((inl&ctx->cipher->block_size) == 0);
    cryp.src=(caddr_t)in;
    cryp.dst=(caddr_t)out;
    cryp.mac=0;
    if(ctx->cipher->iv_len)
	cryp.iv=(caddr_t)ctx->iv;

    if(!ctx->encrypt)
	memcpy(lb,&in[cryp.len-8],8);
	memcpy(lb,&in[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);

    if (ioctl(fd, CIOCCRYPT, &cryp) == -1)
	{
@@ -179,19 +173,49 @@ static int dev_crypto_des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx,
	}

    if(ctx->encrypt)
	memcpy(ctx->iv,&out[cryp.len-8],8);
	memcpy(ctx->iv,&out[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
    else
	memcpy(ctx->iv,lb,8);
	memcpy(ctx->iv,lb,ctx->cipher->iv_len);

    return 1;
    }

static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
					const unsigned char *key,
					const unsigned char *iv, int enc)
    { return dev_crypto_init_key(ctx,CRYPTO_3DES_CBC,key,24); }

#define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher

BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8,
		     0, dev_crypto_des_ede3_init_key,
		     dev_crypto_cleanup, 
		     EVP_CIPHER_set_asn1_iv,
		     EVP_CIPHER_get_asn1_iv,
		     NULL)

static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx,
					const unsigned char *key,
					const unsigned char *iv, int enc)
    { return dev_crypto_init_key(ctx,CRYPTO_ARC4,key,16); }

static const EVP_CIPHER r4_cipher=
    {
    NID_rc4,
    1,16,0,	/* FIXME: key should be up to 256 bytes */
    EVP_CIPH_VARIABLE_LENGTH,
    dev_crypto_rc4_init_key,
    dev_crypto_cipher,
    dev_crypto_cleanup,
    sizeof(session_op),
    NULL,
    NULL,
    NULL
    };

const EVP_CIPHER *EVP_dev_crypto_rc4(void)
    { return &r4_cipher; }

#else
static void *dummy=&dummy;
#endif