Add a demo that reimplements the RSAref glue in form of a dynamically
authorRichard Levitte <levitte@openssl.org>
Wed, 14 Nov 2001 22:42:35 +0000 (22:42 +0000)
committerRichard Levitte <levitte@openssl.org>
Wed, 14 Nov 2001 22:42:35 +0000 (22:42 +0000)
loadable engine.

demos/engines/rsaref/.cvsignore [new file with mode: 0644]
demos/engines/rsaref/Makefile [new file with mode: 0644]
demos/engines/rsaref/README [new file with mode: 0644]
demos/engines/rsaref/rsaref.c [new file with mode: 0644]
demos/engines/rsaref/rsaref.h [new file with mode: 0644]

diff --git a/demos/engines/rsaref/.cvsignore b/demos/engines/rsaref/.cvsignore
new file mode 100644 (file)
index 0000000..76776d9
--- /dev/null
@@ -0,0 +1,12 @@
+librsaref.so.gnu
+librsaref.so.tru64
+librsaref.so.solaris
+librsaref.so.irix
+librsaref.so.hpux32
+librsaref.so.hpux64
+librsaref.so.aix
+librsaref.exp
+doc
+install
+rdemo
+source
diff --git a/demos/engines/rsaref/Makefile b/demos/engines/rsaref/Makefile
new file mode 100644 (file)
index 0000000..c6b8957
--- /dev/null
@@ -0,0 +1,90 @@
+LIBNAME=       librsaref
+SRC=           rsaref.c
+OBJ=           rsaref.o
+HEADER=                rsaref.h
+
+CC=            gcc
+PIC=           -fPIC
+CFLAGS=                -g -I../../../include $(PIC) -DENGINE_DYNAMIC_SUPPORT
+AR=            ar r
+RANLIB=                ranlib
+
+LIB=           $(LIBNAME).a
+SHLIB=         $(LIBNAME).so
+
+all:
+               @echo 'Please choose a system to build on:'
+               @echo ''
+               @echo 'tru64:    Tru64 Unix, Digital Unix, Digital OSF/1'
+               @echo 'solaris:  Solaris'
+               @echo 'irix:     IRIX'
+               @echo 'hpux32:   32-bit HP/UX'
+               @echo 'hpux64:   64-bit HP/UX'
+               @echo 'aix:      AIX'
+               @echo 'gnu:      Generic GNU-based system (gcc and GNU ld)'
+               @echo ''
+
+FORCE.install:
+install:       FORCE.install
+               cd install; \
+                       make -f unix/makefile INCL='-I. -I/usr/include' CFLAGS='$(INCL) -O -c' RSAREFLIB=librsaref.a librsaref.a
+
+gnu:           install $(SHLIB).gnu
+tru64:         install $(SHLIB).tru64
+solaris:       install $(SHLIB).solaris
+irix:          install $(SHLIB).irix
+hpux32:                install $(SHLIB).hpux32
+hpux64:                install $(SHLIB).hpux64
+aix:           install $(SHLIB).aix
+
+$(LIB):                $(OBJ)
+               $(AR) $(LIB) $(OBJ)
+               - $(RANLIB) $(LIB)
+
+LINK_SO=       \
+  ld -r -o $(LIBNAME).o $$ALLSYMSFLAGS $(LIB) install/librsaref.a && \
+  (nm -Pg $(LIBNAME).o | grep ' [BD] ' | cut -f1 -d' ' > $(LIBNAME).exp; \
+   $$SHAREDCMD $$SHAREDFLAGS -o $(SHLIB) $(LIBNAME).o -L ../../.. -lcrypto)
+
+$(SHLIB).gnu:  $(LIB) install/librsaref.a
+               ALLSYMSFLAGS='--whole-archive' \
+               SHAREDFLAGS='-shared -Wl,-soname=$(SHLIB)' \
+               SHAREDCMD='$(CC)'; \
+               $(LINK_SO)
+               touch $(SHLIB).gnu
+$(SHLIB).tru64:        $(LIB) install/librsaref.a
+               ALLSYMSFLAGS='-all' \
+               SHAREDFLAGS='-shared' \
+               SHAREDCMD='$(CC)'; \
+               $(LINK_SO)
+               touch $(SHLIB).tru64
+$(SHLIB).solaris:      $(LIB) install/librsaref.a
+               ALLSYMSFLAGS='-z allextract' \
+               SHAREDFLAGS='-G -h $(SHLIB)' \
+               SHAREDCMD='$(CC)'; \
+               $(LINK_SO)
+               touch $(SHLIB).solaris
+$(SHLIB).irix: $(LIB) install/librsaref.a
+               ALLSYMSFLAGS='-all' \
+               SHAREDFLAGS='-shared -Wl,-soname,$(SHLIB)' \
+               SHAREDCMD='$(CC)'; \
+               $(LINK_SO)
+               touch $(SHLIB).irix
+$(SHLIB).hpux32:       $(LIB) install/librsaref.a
+               ALLSYMSFLAGS='-Fl' \
+               SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $(SHLIB)' \
+               SHAREDCMD='/usr/ccs/bin/ld'; \
+               $(LINK_SO)
+               touch $(SHLIB).hpux32
+$(SHLIB).hpux64:       $(LIB) install/librsaref.a
+               ALLSYMSFLAGS='+forceload' \
+               SHAREDFLAGS='-b -z +h $(SHLIB)' \
+               SHAREDCMD='/usr/ccs/bin/ld'; \
+               $(LINK_SO)
+               touch $(SHLIB).hpux64
+$(SHLIB).aix:  $(LIB) install/librsaref.a
+               ALLSYMSFLAGS='-bnogc' \
+               SHAREDFLAGS='-G -bE:$(LIBNAME).exp -bM:SRE' \
+               SHAREDCMD='$(CC)'; \
+               $(LINK_SO)
+               touch $(SHLIB).aix
diff --git a/demos/engines/rsaref/README b/demos/engines/rsaref/README
new file mode 100644 (file)
index 0000000..00b1f74
--- /dev/null
@@ -0,0 +1,22 @@
+librsaref.so is a demonstration dynamic engine that does RSA
+operations using the old RSAref 2.0 implementation.
+
+To make proper use of this engine, you must download RSAref 2.0
+(search the web for rsaref.tar.Z for example) and unpack it in this
+directory, so you'll end up having the subdirectories "install" and
+"source" among others.
+
+To build, do the following:
+
+       make
+
+This will list a number of available targets to choose from.  Most of
+them are architecture-specific.  The exception is "gnu" which is to be
+used on systems where GNU ld and gcc have been installed in such a way
+that gcc uses GNU ld to link together programs and shared libraries.
+
+The make file assumes you use gcc.  To change that, just reassign CC:
+
+       make CC=cc
+
+The result is librsaref.so, which you can copy to any place you wish.
diff --git a/demos/engines/rsaref/rsaref.c b/demos/engines/rsaref/rsaref.c
new file mode 100644 (file)
index 0000000..bc68a71
--- /dev/null
@@ -0,0 +1,421 @@
+/* Demo of how to construct your own engine and using it.  The basis of this
+   engine is RSAref, an old reference of the RSA algorithm which can still
+   be found a little here and there. */
+
+#include <stdio.h>
+#if 0
+#include "./source/global.h"
+#include "./source/rsaref.h"
+#endif
+#include "rsaref.h"
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/engine.h>
+
+/* Constants used when creating the ENGINE */
+static const char *engine_rsaref_id = "rsaref";
+static const char *engine_rsaref_name = "RSAref engine support";
+
+static int rsaref_destroy(ENGINE *e);
+static int rsaref_init(ENGINE *e);
+static int rsaref_finish(ENGINE *e);
+#if 0
+static int rsaref_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 
+#endif
+
+static int rsaref_private_decrypt(int len, const unsigned char *from,
+       unsigned char *to, RSA *rsa, int padding);
+static int rsaref_private_encrypt(int len, const unsigned char *from,
+       unsigned char *to, RSA *rsa, int padding);
+static int rsaref_public_encrypt(int len, const unsigned char *from,
+       unsigned char *to, RSA *rsa, int padding);
+static int rsaref_public_decrypt(int len, const unsigned char *from,
+       unsigned char *to, RSA *rsa, int padding);
+static int bnref_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m,
+                         BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int rsaref_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
+
+static const ENGINE_CMD_DEFN rsaref_cmd_defns[] = {
+       {0, NULL, NULL, 0}
+       };
+
+static RSA_METHOD rsaref_rsa =
+{
+  "RSAref PKCS#1 RSA",
+  rsaref_public_encrypt,
+  rsaref_public_decrypt,
+  rsaref_private_encrypt,
+  rsaref_private_decrypt,
+  rsaref_mod_exp,
+  bnref_mod_exp,
+  NULL,
+  NULL,
+  0,
+  NULL,
+  NULL,
+  NULL
+};
+
+#ifndef OPENSSL_NO_ERR
+/* Error function codes for use in rsaref operation */
+#define RSAREF_F_BNREF_MOD_EXP                          100
+#define RSAREF_F_RSAREF_BN2BIN                          101
+#define RSAREF_F_RSA_BN2BIN                             102
+#define RSAREF_F_RSA_PRIVATE_DECRYPT                    103
+#define RSAREF_F_RSA_PRIVATE_ENCRYPT                    104
+#define RSAREF_F_RSA_PUBLIC_DECRYPT                     105
+#define RSAREF_F_RSA_PUBLIC_ENCRYPT                     106
+#define RSAREF_F_RSAREF_MOD_EXP                                 108
+#define RSAREF_F_RSAREF_PRIVATE_DECRYPT                         109
+#define RSAREF_F_RSAREF_PRIVATE_ENCRYPT                         110
+#define RSAREF_F_RSAREF_PUBLIC_DECRYPT                  111
+#define RSAREF_F_RSAREF_PUBLIC_ENCRYPT                  112
+/* Error reason codes */
+#define RSAREF_R_CONTENT_ENCODING                       0x0400
+#define RSAREF_R_DATA                                   0x0401
+#define RSAREF_R_DIGEST_ALGORITHM                       0x0402
+#define RSAREF_R_ENCODING                               0x0403
+#define RSAREF_R_ENCRYPTION_ALGORITHM                   0x040d
+#define RSAREF_R_KEY                                    0x0404
+#define RSAREF_R_KEY_ENCODING                           0x0405
+#define RSAREF_R_LEN                                    0x0406
+#define RSAREF_R_MODULUS_LEN                            0x0407
+#define RSAREF_R_NEED_RANDOM                            0x0408
+#define RSAREF_R_PRIVATE_KEY                            0x0409
+#define RSAREF_R_PUBLIC_KEY                             0x040a
+#define RSAREF_R_SIGNATURE                              0x040b
+#define RSAREF_R_SIGNATURE_ENCODING                     0x040c
+
+static ERR_STRING_DATA rsaref_str_functs[] =
+       {
+       /* This first element is changed to match the dynamic 'lib' number */
+{ERR_PACK(0,0,0),                              "rsaref engine code"},
+{ERR_PACK(0,RSAREF_F_BNREF_MOD_EXP,0), "BN_REF_MOD_EXP"},
+{ERR_PACK(0,RSAREF_F_RSAREF_BN2BIN,0), "RSAREF_BN2BIN"},
+{ERR_PACK(0,RSAREF_F_RSA_BN2BIN,0),    "RSA_BN2BIN"},
+{ERR_PACK(0,RSAREF_F_RSA_PRIVATE_DECRYPT,0),   "RSA_private_decrypt"},
+{ERR_PACK(0,RSAREF_F_RSA_PRIVATE_ENCRYPT,0),   "RSA_private_encrypt"},
+{ERR_PACK(0,RSAREF_F_RSA_PUBLIC_DECRYPT,0),    "RSA_public_decrypt"},
+{ERR_PACK(0,RSAREF_F_RSA_PUBLIC_ENCRYPT,0),    "RSA_public_encrypt"},
+{ERR_PACK(0,RSAREF_F_RSAREF_MOD_EXP,0),        "RSA_REF_MOD_EXP"},
+{ERR_PACK(0,RSAREF_F_RSAREF_PRIVATE_DECRYPT,0),        "RSA_REF_PRIVATE_DECRYPT"},
+{ERR_PACK(0,RSAREF_F_RSAREF_PRIVATE_ENCRYPT,0),        "RSA_REF_PRIVATE_ENCRYPT"},
+{ERR_PACK(0,RSAREF_F_RSAREF_PUBLIC_DECRYPT,0), "RSA_REF_PUBLIC_DECRYPT"},
+{ERR_PACK(0,RSAREF_F_RSAREF_PUBLIC_ENCRYPT,0), "RSA_REF_PUBLIC_ENCRYPT"},
+{RSAREF_R_CONTENT_ENCODING               ,"content encoding"},
+{RSAREF_R_DATA                           ,"data"},
+{RSAREF_R_DIGEST_ALGORITHM               ,"digest algorithm"},
+{RSAREF_R_ENCODING                       ,"encoding"},
+{RSAREF_R_ENCRYPTION_ALGORITHM           ,"encryption algorithm"},
+{RSAREF_R_KEY                            ,"key"},
+{RSAREF_R_KEY_ENCODING                   ,"key encoding"},
+{RSAREF_R_LEN                            ,"len"},
+{RSAREF_R_MODULUS_LEN                    ,"modulus len"},
+{RSAREF_R_NEED_RANDOM                    ,"need random"},
+{RSAREF_R_PRIVATE_KEY                    ,"private key"},
+{RSAREF_R_PUBLIC_KEY                     ,"public key"},
+{RSAREF_R_SIGNATURE                      ,"signature"},
+{RSAREF_R_SIGNATURE_ENCODING             ,"signature encoding"},
+{0,NULL}
+       };
+/* The library number we obtain dynamically from the ERR code */
+static int rsaref_err_lib = -1;
+#define RSAREFerr(f,r) ERR_PUT_error(rsaref_err_lib,(f),(r),__FILE__,__LINE__)
+static void rsaref_load_error_strings(void)
+       {
+       if(rsaref_err_lib < 0)
+               {
+               if((rsaref_err_lib = ERR_get_next_error_library()) <= 0)
+                       return;
+               rsaref_str_functs[0].error = ERR_PACK(rsaref_err_lib,0,0);
+               ERR_load_strings(rsaref_err_lib, rsaref_str_functs);
+               }
+       }
+static void rsaref_unload_error_strings(void)
+       {
+       if(rsaref_err_lib >= 0)
+               {
+               ERR_unload_strings(rsaref_err_lib, rsaref_str_functs);
+               rsaref_err_lib = -1;
+               }
+       }
+#else
+#define RSAREFerr(f,r)                                 /* NOP */
+static void rsaref_load_error_strings(void) { }                /* NOP */
+static void rsaref_unload_error_strings(void) { }      /* NOP */
+#endif
+
+/* Now, to our own code */
+
+static int bind_rsaref(ENGINE *e)
+       {
+       const RSA_METHOD *meth1;
+       if(!ENGINE_set_id(e, engine_rsaref_id)
+               || !ENGINE_set_name(e, engine_rsaref_name)
+               || !ENGINE_set_RSA(e, &rsaref_rsa)
+               || !ENGINE_set_destroy_function(e, rsaref_destroy)
+               || !ENGINE_set_init_function(e, rsaref_init)
+               || !ENGINE_set_finish_function(e, rsaref_finish)
+               /* || !ENGINE_set_ctrl_function(e, rsaref_ctrl) */
+               /* || !ENGINE_set_cmd_defns(e, rsaref_cmd_defns) */)
+               return 0;
+
+       /* Ensure the rsaref error handling is set up */
+       rsaref_load_error_strings();
+       return 1;
+       }
+
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static int bind_helper(ENGINE *e, const char *id)
+       {
+       if(id && (strcmp(id, engine_rsaref_id) != 0))
+               return 0;
+       if(!bind_rsaref(e))
+               return 0;
+       return 1;
+       }       
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_rsaref(void)
+       {
+       ENGINE *ret = ENGINE_new();
+       if(!ret)
+               return NULL;
+       if(!bind_rsaref(ret))
+               {
+               ENGINE_free(ret);
+               return NULL;
+               }
+       return ret;
+       }
+
+void ENGINE_load_rsaref(void)
+       {
+       /* Copied from eng_[openssl|dyn].c */
+       ENGINE *toadd = engine_rsaref();
+       if(!toadd) return;
+       ENGINE_add(toadd);
+       ENGINE_free(toadd);
+       ERR_clear_error();
+       }
+#endif
+
+/* Initiator which is only present to make sure this engine looks available */
+static int rsaref_init(ENGINE *e)
+       {
+       return 1;
+       }
+
+/* Finisher which is only present to make sure this engine looks available */
+static int rsaref_finish(ENGINE *e)
+       {
+       return 1;
+       }
+
+/* Destructor (complements the "ENGINE_ncipher()" constructor) */
+static int rsaref_destroy(ENGINE *e)
+       {
+       rsaref_unload_error_strings();
+       return 1;
+       }
+
+static int rsaref_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
+       {
+       RSAREFerr(RSAREF_F_RSAREF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+       return(0);
+       }
+
+static int bnref_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+       {
+       RSAREFerr(RSAREF_F_BNREF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+       return(0);
+       }
+
+/* unsigned char *to:  [max]    */
+static int RSAref_bn2bin(BIGNUM *from, unsigned char *to, int max)
+       {
+       int i;
+
+       i=BN_num_bytes(from);
+       if (i > max)
+               {
+               RSAREFerr(RSAREF_F_RSAREF_BN2BIN,RSAREF_R_LEN);
+               return(0);
+               }
+
+       memset(to,0,(unsigned int)max);
+       if (!BN_bn2bin(from,&(to[max-i])))
+               return(0);
+       return(1);
+       }
+
+#ifdef undef
+/* unsigned char *from:  [max]    */
+static BIGNUM *RSAref_bin2bn(unsigned char *from, BIGNUM *to, int max)
+       {
+       int i;
+       BIGNUM *ret;
+
+       for (i=0; i<max; i++)
+               if (from[i]) break;
+
+       ret=BN_bin2bn(&(from[i]),max-i,to);
+       return(ret);
+       }
+
+static int RSAref_Public_ref2eay(RSArefPublicKey *from, RSA *to)
+       {
+       to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN);
+       to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN);
+       if ((to->n == NULL) || (to->e == NULL)) return(0);
+       return(1);
+       }
+#endif
+
+static int RSAref_Public_eay2ref(RSA *from, RSArefPublicKey *to)
+       {
+       to->bits=BN_num_bits(from->n);
+       if (!RSAref_bn2bin(from->n,to->m,RSAref_MAX_LEN)) return(0);
+       if (!RSAref_bn2bin(from->e,to->e,RSAref_MAX_LEN)) return(0);
+       return(1);
+       }
+
+#ifdef undef
+static int RSAref_Private_ref2eay(RSArefPrivateKey *from, RSA *to)
+       {
+       if ((to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN)) == NULL)
+               return(0);
+       if ((to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN)) == NULL)
+               return(0);
+       if ((to->d=RSAref_bin2bn(from->d,NULL,RSAref_MAX_LEN)) == NULL)
+               return(0);
+       if ((to->p=RSAref_bin2bn(from->prime[0],NULL,RSAref_MAX_PLEN)) == NULL)
+               return(0);
+       if ((to->q=RSAref_bin2bn(from->prime[1],NULL,RSAref_MAX_PLEN)) == NULL)
+               return(0);
+       if ((to->dmp1=RSAref_bin2bn(from->pexp[0],NULL,RSAref_MAX_PLEN))
+               == NULL)
+               return(0);
+       if ((to->dmq1=RSAref_bin2bn(from->pexp[1],NULL,RSAref_MAX_PLEN))
+               == NULL)
+               return(0);
+       if ((to->iqmp=RSAref_bin2bn(from->coef,NULL,RSAref_MAX_PLEN)) == NULL)
+               return(0);
+       return(1);
+       }
+#endif
+
+static int RSAref_Private_eay2ref(RSA *from, RSArefPrivateKey *to)
+       {
+       to->bits=BN_num_bits(from->n);
+       if (!RSAref_bn2bin(from->n,to->m,RSAref_MAX_LEN)) return(0);
+       if (!RSAref_bn2bin(from->e,to->e,RSAref_MAX_LEN)) return(0);
+       if (!RSAref_bn2bin(from->d,to->d,RSAref_MAX_LEN)) return(0);
+       if (!RSAref_bn2bin(from->p,to->prime[0],RSAref_MAX_PLEN)) return(0);
+       if (!RSAref_bn2bin(from->q,to->prime[1],RSAref_MAX_PLEN)) return(0);
+       if (!RSAref_bn2bin(from->dmp1,to->pexp[0],RSAref_MAX_PLEN)) return(0);
+       if (!RSAref_bn2bin(from->dmq1,to->pexp[1],RSAref_MAX_PLEN)) return(0);
+       if (!RSAref_bn2bin(from->iqmp,to->coef,RSAref_MAX_PLEN)) return(0);
+       return(1);
+       }
+
+static int rsaref_private_decrypt(int len, const unsigned char *from, unsigned char *to,
+            RSA *rsa, int padding)
+       {
+       int i,outlen= -1;
+       RSArefPrivateKey RSAkey;
+
+       if (!RSAref_Private_eay2ref(rsa,&RSAkey))
+               goto err;
+       if ((i=RSAPrivateDecrypt(to,&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
+               {
+               RSAREFerr(RSAREF_F_RSA_REF_PRIVATE_DECRYPT,i);
+               outlen= -1;
+               }
+err:
+       memset(&RSAkey,0,sizeof(RSAkey));
+       return(outlen);
+       }
+
+static int rsaref_private_encrypt(int len, const unsigned char *from, unsigned char *to,
+            RSA *rsa, int padding)
+       {
+       int i,outlen= -1;
+       RSArefPrivateKey RSAkey;
+
+       if (padding != RSA_PKCS1_PADDING)
+               {
+               RSAREFerr(RSAREF_F_RSA_REF_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+               goto err;
+       }
+       if (!RSAref_Private_eay2ref(rsa,&RSAkey))
+               goto err;
+       if ((i=RSAPrivateEncrypt(to,&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
+               {
+               RSAREFerr(RSAREF_F_RSA_REF_PRIVATE_ENCRYPT,i);
+               outlen= -1;
+               }
+err:
+       memset(&RSAkey,0,sizeof(RSAkey));
+       return(outlen);
+       }
+
+static int rsaref_public_decrypt(int len, const unsigned char *from, unsigned char *to,
+            RSA *rsa, int padding)
+       {
+       int i,outlen= -1;
+       RSArefPublicKey RSAkey;
+
+       if (!RSAref_Public_eay2ref(rsa,&RSAkey))
+               goto err;
+       if ((i=RSAPublicDecrypt(to,&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
+               {
+               RSAREFerr(RSAREF_F_RSA_REF_PUBLIC_DECRYPT,i);
+               outlen= -1;
+               }
+err:
+       memset(&RSAkey,0,sizeof(RSAkey));
+       return(outlen);
+       }
+
+static int rsaref_public_encrypt(int len, const unsigned char *from, unsigned char *to,
+            RSA *rsa, int padding)
+       {
+       int outlen= -1;
+       int i;
+       RSArefPublicKey RSAkey;
+       RSARandomState rnd;
+       unsigned char buf[16];
+
+       if (padding != RSA_PKCS1_PADDING && padding != RSA_SSLV23_PADDING) 
+               {
+               RSAREFerr(RSAREF_F_RSA_REF_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+               goto err;
+               }
+       
+       R_RandomInit(&rnd);
+       R_GetRandomBytesNeeded((unsigned int *)&i,&rnd);
+       while (i > 0)
+               {
+               if (RAND_bytes(buf,16) <= 0)
+                       goto err;
+               R_RandomUpdate(&rnd,buf,(unsigned int)((i>16)?16:i));
+               i-=16;
+               }
+
+       if (!RSAref_Public_eay2ref(rsa,&RSAkey))
+               goto err;
+       if ((i=RSAPublicEncrypt(to,&outlen,(unsigned char *)from,len,&RSAkey,&rnd)) != 0)
+               {
+               RSAREFerr(RSAREF_F_RSA_REF_PUBLIC_ENCRYPT,i);
+               outlen= -1;
+               goto err;
+               }
+err:
+       memset(&RSAkey,0,sizeof(RSAkey));
+       R_RandomFinal(&rnd);
+       memset(&rnd,0,sizeof(rnd));
+       return(outlen);
+       }
diff --git a/demos/engines/rsaref/rsaref.h b/demos/engines/rsaref/rsaref.h
new file mode 100644 (file)
index 0000000..498449f
--- /dev/null
@@ -0,0 +1,180 @@
+/* rsaref/rsaref.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RSAREF_H
+#define HEADER_RSAREF_H
+
+#ifndef NO_RSA
+#include <openssl/rsa.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* RSAeuro */
+/*#define  RSAref_MAX_BITS             2048*/
+
+/* RSAref */
+#define  RSAref_MAX_BITS               1024
+
+#define RSAref_MIN_BITS                508
+#define RSAref_MAX_LEN         ((RSAref_MAX_BITS+7)/8)
+#define RSAref_MAX_PBITS       (RSAref_MAX_BITS+1)/2
+#define RSAref_MAX_PLEN                ((RSAref_MAX_PBITS+7)/8)
+
+typedef struct RSArefPublicKey_st
+       {
+       unsigned int bits;
+       unsigned char m[RSAref_MAX_LEN];
+       unsigned char e[RSAref_MAX_LEN];
+       } RSArefPublicKey;
+
+typedef struct RSArefPrivateKey_st
+       {
+       unsigned int bits;
+       unsigned char m[RSAref_MAX_LEN];
+       unsigned char e[RSAref_MAX_LEN];
+       unsigned char d[RSAref_MAX_LEN];
+       unsigned char prime[2][RSAref_MAX_PLEN];/* p & q */
+       unsigned char pexp[2][RSAref_MAX_PLEN]; /* dmp1 & dmq1 */
+       unsigned char coef[RSAref_MAX_PLEN];    /* iqmp */
+       } RSArefPrivateKey;
+
+typedef struct RSARandomState_st
+       {
+       unsigned int needed;
+       unsigned char state[16];
+       unsigned int outputnum;
+       unsigned char output[16];
+       } RSARandomState;
+
+#define RE_CONTENT_ENCODING 0x0400
+#define RE_DATA 0x0401
+#define RE_DIGEST_ALGORITHM 0x0402
+#define RE_ENCODING 0x0403
+#define RE_KEY 0x0404
+#define RE_KEY_ENCODING 0x0405
+#define RE_LEN 0x0406
+#define RE_MODULUS_LEN 0x0407
+#define RE_NEED_RANDOM 0x0408
+#define RE_PRIVATE_KEY 0x0409
+#define RE_PUBLIC_KEY 0x040a
+#define RE_SIGNATURE 0x040b
+#define RE_SIGNATURE_ENCODING 0x040c
+#define RE_ENCRYPTION_ALGORITHM 0x040d
+
+int RSAPrivateDecrypt(unsigned char *to, int *outlen, unsigned char *from,
+       int len, RSArefPrivateKey *RSAkey);
+int RSAPrivateEncrypt(unsigned char *to, int *outlen, unsigned char *from,
+       int len, RSArefPrivateKey *RSAkey);
+int RSAPublicDecrypt(unsigned char *to, int *outlen, unsigned char *from,
+       int len, RSArefPublicKey *RSAkey);
+int RSAPublicEncrypt(unsigned char *to, int *outlen, unsigned char *from,
+       int len, RSArefPublicKey *RSAkey,RSARandomState *rnd);
+int R_RandomInit(RSARandomState *rnd);
+int R_GetRandomBytesNeeded(unsigned int *,RSARandomState *rnd);
+int R_RandomUpdate(RSARandomState *rnd, unsigned char *data, unsigned int n);
+int R_RandomFinal(RSARandomState *rnd);
+
+void ERR_load_RSAREF_strings(void );
+RSA_METHOD *RSA_PKCS1_RSAref(void );
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the RSAREF functions. */
+
+/* Function codes. */
+#define RSAREF_F_BN_REF_MOD_EXP                                 100
+#define RSAREF_F_RSAREF_BN2BIN                          101
+#define RSAREF_F_RSA_BN2BIN                             102
+#define RSAREF_F_RSA_PRIVATE_DECRYPT                    103
+#define RSAREF_F_RSA_PRIVATE_ENCRYPT                    104
+#define RSAREF_F_RSA_PUBLIC_DECRYPT                     105
+#define RSAREF_F_RSA_PUBLIC_ENCRYPT                     106
+#define RSAREF_F_RSA_REF_BN2BIN                                 107
+#define RSAREF_F_RSA_REF_MOD_EXP                        108
+#define RSAREF_F_RSA_REF_PRIVATE_DECRYPT                109
+#define RSAREF_F_RSA_REF_PRIVATE_ENCRYPT                110
+#define RSAREF_F_RSA_REF_PUBLIC_DECRYPT                         111
+#define RSAREF_F_RSA_REF_PUBLIC_ENCRYPT                         112
+
+/* Reason codes. */
+#define RSAREF_R_CONTENT_ENCODING                       0x0400
+#define RSAREF_R_DATA                                   0x0401
+#define RSAREF_R_DIGEST_ALGORITHM                       0x0402
+#define RSAREF_R_ENCODING                               0x0403
+#define RSAREF_R_ENCRYPTION_ALGORITHM                   0x040d
+#define RSAREF_R_KEY                                    0x0404
+#define RSAREF_R_KEY_ENCODING                           0x0405
+#define RSAREF_R_LEN                                    0x0406
+#define RSAREF_R_MODULUS_LEN                            0x0407
+#define RSAREF_R_NEED_RANDOM                            0x0408
+#define RSAREF_R_PRIVATE_KEY                            0x0409
+#define RSAREF_R_PUBLIC_KEY                             0x040a
+#define RSAREF_R_SIGNATURE                              0x040b
+#define RSAREF_R_SIGNATURE_ENCODING                     0x040c
+
+#endif