aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.14/950-0431-Add-hy28b-2017-model-device-tree-overlay-2721.patch
blob: 8b795562b06c096900428a9ba52c9020ccea8019 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
From a3d3b80d8a028e7cec393c02c1a96c5e632e7b30 Mon Sep 17 00:00:00 2001
From: Hans-Wilhelm Warlo <5417271+hanswilw@users.noreply.github.com>
Date: Tue, 16 Oct 2018 18:20:48 +0200
Subject: [PATCH 431/454] Add hy28b 2017 model device tree overlay (#2721)

The 2017 version of the hy28b display requires a different
initialisation sequence.

Signed-off-by: Hans-Wilhelm Warlo <hw@warlo.no>
---
 arch/arm/boot/dts/overlays/Makefile           |   1 +
 arch/arm/boot/dts/overlays/README             |  19 +++
 .../boot/dts/overlays/hy28b-2017-overlay.dts  | 152 ++++++++++++++++++
 3 files changed, 172 insertions(+)
 create mode 100644 arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts

--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -51,6 +51,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
 	hifiberry-digi-pro.dtbo \
 	hy28a.dtbo \
 	hy28b.dtbo \
+	hy28b-2017.dtbo \
 	i2c-bcm2708.dtbo \
 	i2c-gpio.dtbo \
 	i2c-mux.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -792,6 +792,25 @@ Params: speed                   Display
         ledgpio                 GPIO used to control backlight
 
 
+Name:   hy28b-2017
+Info:   HY28B 2017 version - 2.8" TFT LCD Display Module by HAOYU Electronics
+        Default values match Texy's display shield
+Load:   dtoverlay=hy28b-2017,<param>=<val>
+Params: speed                   Display SPI bus speed
+
+        rotate                  Display rotation {0,90,180,270}
+
+        fps                     Delay between frame updates
+
+        debug                   Debug output level {0-7}
+
+        xohms                   Touchpanel sensitivity (X-plate resistance)
+
+        resetgpio               GPIO used to reset controller
+
+        ledgpio                 GPIO used to control backlight
+
+
 Name:   i2c-bcm2708
 Info:   Fall back to the i2c_bcm2708 driver for the i2c_arm bus.
 Load:   dtoverlay=i2c-bcm2708
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts
@@ -0,0 +1,152 @@
+/*
+ * Device Tree overlay for HY28b display shield by Texy.
+ * Modified for 2017 version with ILI9325 D chip
+ */
+
+/dts-v1/;
+/plugin/;
+
+/ {
+	compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
+
+	fragment@0 {
+		target = <&spi0>;
+		__overlay__ {
+			status = "okay";
+		};
+	};
+
+	fragment@1 {
+		target = <&spidev0>;
+		__overlay__ {
+			status = "disabled";
+		};
+	};
+
+	fragment@2 {
+		target = <&spidev1>;
+		__overlay__ {
+			status = "disabled";
+		};
+	};
+
+	fragment@3 {
+		target = <&gpio>;
+		__overlay__ {
+			hy28b_pins: hy28b_pins {
+				brcm,pins = <17 25 18>;
+				brcm,function = <0 1 1>; /* in out out */
+			};
+		};
+	};
+
+	fragment@4 {
+		target = <&spi0>;
+		__overlay__ {
+			/* needed to avoid dtc warning */
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hy28b: hy28b@0{
+				compatible = "ilitek,ili9325";
+				reg = <0>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&hy28b_pins>;
+
+				spi-max-frequency = <48000000>;
+				spi-cpol;
+				spi-cpha;
+				rotate = <270>;
+				bgr;
+				fps = <50>;
+				buswidth = <8>;
+				startbyte = <0x70>;
+				reset-gpios = <&gpio 25 0>;
+				led-gpios = <&gpio 18 1>;
+
+				init = <0x10000e5 0x78F0
+					0x1000001 0x0100
+					0x1000002 0x0700
+				        0x1000003 0x1030
+					0x1000004 0x0000
+					0x1000008 0x0207
+					0x1000009 0x0000
+				        0x100000a 0x0000
+					0x100000c 0x0000
+					0x100000d 0x0000
+					0x100000f 0x0000
+				        0x1000010 0x0000
+					0x1000011 0x0007
+					0x1000012 0x0000
+					0x1000013 0x0000
+					0x1000007 0x0001
+				        0x2000032
+				        0x2000032
+				        0x2000032
+				        0x2000032
+					0x1000010 0x1090
+					0x1000011 0x0227
+				        0x2000032
+					0x1000012 0x001f
+				        0x2000032
+				        0x1000013 0x1500
+					0x1000029 0x0027
+					0x100002b 0x000d
+				        0x2000032
+				        0x1000020 0x0000
+					0x1000021 0x0000
+				        0x2000032
+					0x1000030 0x0000
+					0x1000031 0x0707
+					0x1000032 0x0307
+					0x1000035 0x0200
+					0x1000036 0x0008
+					0x1000037 0x0004
+					0x1000038 0x0000
+					0x1000039 0x0707
+					0x100003c 0x0002
+					0x100003d 0x1d04
+					0x1000050 0x0000
+				        0x1000051 0x00ef
+					0x1000052 0x0000
+					0x1000053 0x013f
+					0x1000060 0xa700
+				        0x1000061 0x0001
+					0x100006a 0x0000
+					0x1000080 0x0000
+					0x1000081 0x0000
+				        0x1000082 0x0000
+					0x1000083 0x0000
+					0x1000084 0x0000
+					0x1000085 0x0000
+				        0x1000090 0x0010
+					0x1000092 0x0600
+					0x1000007 0x0133>;
+				debug = <0>;
+			};
+
+			hy28b_ts: hy28b-ts@1 {
+				compatible = "ti,ads7846";
+				reg = <1>;
+
+				spi-max-frequency = <2000000>;
+				interrupts = <17 2>; /* high-to-low edge triggered */
+				interrupt-parent = <&gpio>;
+				pendown-gpio = <&gpio 17 0>;
+				ti,x-plate-ohms = /bits/ 16 <100>;
+				ti,pressure-max = /bits/ 16 <255>;
+			};
+		};
+	};
+	__overrides__ {
+		speed = 	<&hy28b>,"spi-max-frequency:0";
+		rotate = 	<&hy28b>,"rotate:0";
+		fps = 		<&hy28b>,"fps:0";
+		debug = 	<&hy28b>,"debug:0";
+		xohms =		<&hy28b_ts>,"ti,x-plate-ohms;0";
+		resetgpio =	<&hy28b>,"reset-gpios:4",
+				<&hy28b_pins>, "brcm,pins:4";
+		ledgpio =	<&hy28b>,"led-gpios:4",
+				<&hy28b_pins>, "brcm,pins:8";
+	};
+};
ef='#n689'>689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
--- a/Configure
+++ b/Configure
@@ -36,6 +36,8 @@ my $usage="Usage: Configure [no-<cipher>
 #		(Default: KRB5_DIR/include)
 # --with-krb5-flavor  Declare what flavor of Kerberos 5 is used.  Currently
 #		supported values are "MIT" and "Heimdal".  A value is required.
+# --with-cryptodev Force support for cryptodev (ie., ocf-linux)
+# --with-cryptodev-digests Force support for cryptodev digests (generally slow)
 #
 # --test-sanity Make a number of sanity checks on the data in this file.
 #               This is a debugging tool for OpenSSL developers.
@@ -554,6 +556,10 @@ my %table=(
 ##### Compaq Non-Stop Kernel (Tandem)
 "tandem-c89","c89:-Ww -D__TANDEM -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D_TANDEM_SOURCE -DB_ENDIAN::(unknown):::THIRTY_TWO_BIT:::",
 
+# uClinux
+"uClinux-dist","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):BN_LLONG::::::::::::\$(LIBSSL_dlfcn):linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}",
+"uClinux-dist64","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):SIXTY_FOUR_BIT_LONG::::::::::::\$(LIBSSL_dlfcn):linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}",
+
 );
 
 my @MK1MF_Builds=qw(VC-WIN64I VC-WIN64A
@@ -610,6 +616,8 @@ my $montasm=1;   # but "no-montasm" is d
 my $no_asm=0;
 my $no_dso=0;
 my $no_gmp=0;
+my $have_cryptodev=0;
+my $use_cryptodev_digests=0;
 my @skip=();
 my $Makefile="Makefile";
 my $des_locl="crypto/des/des_locl.h";
@@ -758,6 +766,14 @@ PROCESS_ARGS:
 			{
 			exit(&test_sanity());
 			}
+		elsif (/^--with-cryptodev$/)
+			{
+				$have_cryptodev = 1;
+			}
+		elsif (/^--with-cryptodev-digests$/)
+			{
+				$use_cryptodev_digests = 1;
+			}
 		elsif (/^--strict-warnings/)
 			{
 			$strict_warnings = 1;
@@ -1055,6 +1071,7 @@ foreach (sort (keys %disabled))
 			print " OPENSSL_NO_$ALGO";
 		
 			if (/^err$/)	{ $flags .= "-DOPENSSL_NO_ERR "; }
+			elsif (/^hw$/)	{ $flags .= "-DOPENSSL_NO_HW "; }
 			elsif (/^asm$/)	{ $no_asm = 1; }
 			}
 		else
@@ -1184,6 +1201,16 @@ if (!$no_krb5)
 		   $withargs{"krb5-dir"} ne "";
 	}
 
+# enable the linux cryptodev (ocf-linux) support
+if ($have_cryptodev)
+	{
+	if ($use_cryptodev_digests)
+		{
+		$cflags = "-DUSE_CRYPTODEV_DIGESTS $cflags";
+		}
+	$cflags = "-DHAVE_CRYPTODEV $cflags";
+	}
+
 # The DSO code currently always implements all functions so that no
 # applications will have to worry about that from a compilation point
 # of view. However, the "method"s may return zero unless that platform
--- a/INSTALL
+++ b/INSTALL
@@ -103,6 +103,12 @@
                 define preprocessor symbols, specify additional libraries,
                 library directories or other compiler options.
 
+  --with-cryptodev Enabled the BSD cryptodev engine even if we are not using
+		BSD.  Useful if you are running ocf-linux or something
+		similar.  Once enabled you can also enable the use of
+		cryptodev digests,  with is usually slower unless you have
+		large amounts data.  Use --with-cryptodev-digests to force
+		it.
 
  Installation in Detail
  ----------------------
--- a/Makefile.org
+++ b/Makefile.org
@@ -499,7 +499,7 @@ files:
 
 links:
 	@$(PERL) $(TOP)/util/mkdir-p.pl include/openssl
-	@$(PERL) $(TOP)/util/mklink.pl include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl include/openssl $(HEADER) $(EXHEADER)
 	@set -e; target=links; $(RECURSIVE_BUILD_CMD)
 	@if [ -z "$(FIPSCANLIB)" ]; then \
 		set -e; target=links; dir=fips ; $(BUILD_CMD) ; \
--- a/Makefile.shared
+++ b/Makefile.shared
@@ -6,13 +6,13 @@
 # properly
 
 # CC contains the current compiler.  This one MUST be defined
-CC=cc
-CFLAGS=$(CFLAG)
+CC?=cc
+CFLAGS?=$(CFLAG)
 # LDFLAGS contains flags to be used when temporary object files (when building
 # shared libraries) are created, or when an application is linked.
 # SHARED_LDFLAGS contains flags to be used when the shared library is created.
-LDFLAGS=
-SHARED_LDFLAGS=
+LDFLAGS?=
+SHARED_LDFLAGS?=
 
 # LIBNAME contains just the name of the library, without prefix ("lib"
 # on Unix, "cyg" for certain forms under Cygwin...) or suffix (.a, .so,
--- a/config
+++ b/config
@@ -270,7 +270,7 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${
 		echo "ppc-apple-darwin${VERSION}"
 		;;
 	    *)
-		echo "i386-apple-darwin${VERSION}"
+		echo "${MACHINE}-apple-darwin${VERSION}"
 		;;
 	esac
 	exit 0
@@ -399,7 +399,7 @@ exit 0
 # this is where the translation occurs into SSLeay terms
 # ---------------------------------------------------------------------------
 
-GCCVER=`(gcc -dumpversion) 2>/dev/null`
+GCCVER=`(${CC:-gcc} -dumpversion) 2>/dev/null`
 if [ "$GCCVER" != "" ]; then
   # then strip off whatever prefix egcs prepends the number with...
   # Hopefully, this will work for any future prefixes as well.
@@ -488,6 +488,12 @@ echo Operating system: $GUESSOS
 # script above so we end up with values in vars but that would take
 # more time that I want to waste at the moment
 case "$GUESSOS" in
+  uClinux*64*)
+    OUT=uClinux-dist64
+	;;
+  uClinux*)
+    OUT=uClinux-dist
+	;;
   mips2-sgi-irix)
 	CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
 	CPU=${CPU:-0}
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -112,7 +112,7 @@
 #ifndef HEADER_APPS_H
 #define HEADER_APPS_H
 
-#include "e_os.h"
+#include <openssl/e_os.h>
 
 #include <openssl/bio.h>
 #include <openssl/x509.h>
--- a/apps/progs.h
+++ b/apps/progs.h
@@ -129,7 +129,9 @@ FUNCTION functions[] = {
 #ifndef OPENSSL_NO_ENGINE
 	{FUNC_TYPE_GENERAL,"engine",engine_main},
 #endif
+#ifndef OPENSSL_NO_OCSP
 	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
+#endif
 	{FUNC_TYPE_GENERAL,"prime",prime_main},
 #ifndef OPENSSL_NO_MD2
 	{FUNC_TYPE_MD,"md2",dgst_main},
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -302,7 +302,7 @@ static const char *names[ALGOR_NUM]={
   "evp","sha256","sha512",
   "aes-128 ige","aes-192 ige","aes-256 ige"};
 static double results[ALGOR_NUM][SIZE_NUM];
-static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
+static int lengths[SIZE_NUM]={16,64,256,1024,2*1024,4*1024};
 #ifndef OPENSSL_NO_RSA
 static double rsa_results[RSA_NUM][2];
 #endif
@@ -342,6 +342,82 @@ static SIGRETTYPE sig_done(int sig)
 #define START	0
 #define STOP	1
 
+static int do_cpu = 0;
+
+#ifdef __linux__
+
+#define HAVE_CPU_USAGE	1
+
+/*
+ * record CPU usage as well
+ */
+
+struct cpu_stat {
+	unsigned int	user;
+	unsigned int	nice;
+	unsigned int	system;
+	unsigned int	idle;
+	unsigned int	total;
+};
+
+static unsigned int cpu_usage[ALGOR_NUM][SIZE_NUM];
+static unsigned int rsa_cpu_usage[RSA_NUM][2];
+static unsigned int dsa_cpu_usage[DSA_NUM][2];
+static struct cpu_stat cpu_start, cpu_finish;
+
+static void
+get_cpu(int s)
+{
+	FILE *fp = NULL;
+	unsigned char	buf[80];
+	struct cpu_stat *st = s == START ? &cpu_start : &cpu_finish;
+
+	memset(st, 0, sizeof(*st));
+
+	if (fp == NULL)
+		fp = fopen("/proc/stat", "r");
+	if (!fp)
+		return;
+	if (fseek(fp, 0, SEEK_SET) == -1) {
+		fclose(fp);
+		return;
+	}
+	fscanf(fp, "%s %d %d %d %d", &buf[0], &st->user, &st->nice,
+		&st->system, &st->idle);
+	st->total = st->user + st->nice + st->system + st->idle;
+	fclose(fp);
+}
+
+static unsigned int
+calc_cpu()
+{
+	unsigned int total, res;
+
+	total  = cpu_finish.total - cpu_start.total;
+	if (total <= 0)
+		return 0;
+#if 1 // busy
+	res   = ((cpu_finish.system + cpu_finish.user + cpu_finish.nice) -
+			 (cpu_start.system + cpu_start.user + cpu_start.nice)) *
+			 100 / total;
+#endif
+#if 0 // system
+	res   = (cpu_finish.system - cpu_start.system) * 100 / total;
+#endif
+#if 0 // user
+	res   = (cpu_finish.user   - cpu_start.user)   * 100 / total;
+#endif
+#if 0 // nice
+	res   = (cpu_finish.nice   - cpu_start.nice)   * 100 / total;
+#endif
+#if 0 // idle
+	res   = (cpu_finish.idle   - cpu_start.idle)   * 100 / total;
+#endif
+	return(res);
+}
+
+#endif
+
 #if defined(OPENSSL_SYS_NETWARE)
 
    /* for NetWare the best we can do is use clock() which returns the
@@ -372,6 +448,9 @@ static double Time_F(int s)
 	{
 	double ret;
 
+	if (do_cpu)
+		get_cpu(s);
+
 #ifdef USE_TOD
 	if(usertime)
 		{
@@ -839,6 +918,14 @@ int MAIN(int argc, char **argv)
 			j--;	/* Otherwise, -elapsed gets confused with
 				   an algorithm. */
 			}
+#ifdef HAVE_CPU_USAGE
+		else if	((argc > 0) && (strcmp(*argv,"-cpu") == 0))
+			{
+			do_cpu = 1;
+			j--;	/* Otherwise, -cpu gets confused with
+				   an algorithm. */
+			}
+#endif
 		else if	((argc > 0) && (strcmp(*argv,"-evp") == 0))
 			{
 			argc--;
@@ -1267,6 +1354,9 @@ int MAIN(int argc, char **argv)
 #ifndef NO_FORK
 			BIO_printf(bio_err,"-multi n        run n benchmarks in parallel.\n");
 #endif
+#ifdef HAVE_CPU_USAGE
+			BIO_printf(bio_err,"-cpu            calculate cpu utilisation.\n");
+#endif
 			goto end;
 			}
 		argc--;
@@ -1274,11 +1364,6 @@ int MAIN(int argc, char **argv)
 		j++;
 		}
 
-#ifndef NO_FORK
-	if(multi && do_multi(multi))
-		goto show_res;
-#endif
-
 	if (j == 0)
 		{
 		for (i=0; i<ALGOR_NUM; i++)
@@ -1612,6 +1697,11 @@ int MAIN(int argc, char **argv)
 	signal(SIGALRM,sig_done);
 #endif /* SIGALRM */
 
+#ifndef NO_FORK /* Do this a late as possible to give better CPU readings */
+	if(multi && do_multi(multi))
+		goto show_res;
+#endif
+
 #ifndef OPENSSL_NO_MD2
 	if (doit[D_MD2])
 		{
@@ -2041,8 +2131,6 @@ int MAIN(int argc, char **argv)
 				/* -O3 -fschedule-insns messes up an
 				 * optimization here!  names[D_EVP]
 				 * somehow becomes NULL */
-				print_message(names[D_EVP],save_count,
-					lengths[j]);
 
 				EVP_CIPHER_CTX_init(&ctx);
 				if(decrypt)
@@ -2051,6 +2139,9 @@ int MAIN(int argc, char **argv)
 					EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
 				EVP_CIPHER_CTX_set_padding(&ctx, 0);
 
+				print_message(names[D_EVP],save_count,
+					lengths[j]);
+
 				Time_F(START);
 				if(decrypt)
 					for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
@@ -2115,6 +2206,8 @@ int MAIN(int argc, char **argv)
 					}
 				}
 			d=Time_F(STOP);
+			if (do_cpu)
+				rsa_cpu_usage[j][0] = calc_cpu();
 			BIO_printf(bio_err,mr ? "+R1:%ld:%d:%.2f\n"
 				   : "%ld %d bit private RSA's in %.2fs\n",
 				   count,rsa_bits[j],d);
@@ -2150,6 +2243,8 @@ int MAIN(int argc, char **argv)
 					}
 				}
 			d=Time_F(STOP);
+			if (do_cpu)
+				rsa_cpu_usage[j][1] = calc_cpu();
 			BIO_printf(bio_err,mr ? "+R2:%ld:%d:%.2f\n"
 				   : "%ld %d bit public RSA's in %.2fs\n",
 				   count,rsa_bits[j],d);
@@ -2209,6 +2304,8 @@ int MAIN(int argc, char **argv)
 					}
 				}
 			d=Time_F(STOP);
+			if (do_cpu)
+				dsa_cpu_usage[j][0] = calc_cpu();
 			BIO_printf(bio_err,mr ? "+R3:%ld:%d:%.2f\n"
 				   : "%ld %d bit DSA signs in %.2fs\n",
 				   count,dsa_bits[j],d);
@@ -2244,6 +2341,8 @@ int MAIN(int argc, char **argv)
 					}
 				}
 			d=Time_F(STOP);
+			if (do_cpu)
+				dsa_cpu_usage[j][1] = calc_cpu();
 			BIO_printf(bio_err,mr ? "+R4:%ld:%d:%.2f\n"
 				   : "%ld %d bit DSA verify in %.2fs\n",
 				   count,dsa_bits[j],d);
@@ -2538,14 +2637,23 @@ show_res:
 			fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n"); 
 			fprintf(stdout,"type        ");
 			}
-		for (j=0;  j<SIZE_NUM; j++)
+		for (j=0;  j<SIZE_NUM; j++) {
 			fprintf(stdout,mr ? ":%d" : "%7d bytes",lengths[j]);
+			if (do_cpu && !mr)
+				fprintf(stdout, " /cpu");
+		}
 		fprintf(stdout,"\n");
 		}
 
 	for (k=0; k<ALGOR_NUM; k++)
 		{
 		if (!doit[k]) continue;
+		if (k == D_EVP) {
+			if (evp_cipher)
+				names[D_EVP]=OBJ_nid2ln(evp_cipher->nid);
+			else
+				names[D_EVP]=OBJ_nid2ln(evp_md->type);
+		}
 		if(mr)
 			fprintf(stdout,"+F:%d:%s",k,names[k]);
 		else
@@ -2556,6 +2664,8 @@ show_res:
 				fprintf(stdout," %11.2fk",results[k][j]/1e3);
 			else
 				fprintf(stdout,mr ? ":%.2f" : " %11.2f ",results[k][j]);
+			if (do_cpu)
+				fprintf(stdout, mr ? "/%d" : "/%%%-3d", cpu_usage[k][j]);
 			}
 		fprintf(stdout,"\n");
 		}
@@ -2570,13 +2680,18 @@ show_res:
 			j=0;
 			}
 		if(mr)
-			fprintf(stdout,"+F2:%u:%u:%f:%f\n",
-				k,rsa_bits[k],rsa_results[k][0],
-				rsa_results[k][1]);
-		else
-			fprintf(stdout,"rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
-				rsa_bits[k],rsa_results[k][0],rsa_results[k][1],
-				1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
+			fprintf(stdout,"+F2:%u:%u:%f", k,rsa_bits[k],rsa_results[k][0]);
+		else
+			fprintf(stdout,"rsa %4u bits %8.6fs",rsa_bits[k],rsa_results[k][0]);
+		if (do_cpu)
+			fprintf(stdout, mr ? "/%d": "/%%%-3d", rsa_cpu_usage[k][0]);
+		fprintf(stdout, mr ? ":%f" : " %8.6fs", rsa_results[k][1]);
+		if (do_cpu)
+			fprintf(stdout, mr ? "/%d": "/%%%-3d", rsa_cpu_usage[k][1]);
+		if(!mr)
+			fprintf(stdout, " %8.1f %8.1f",
+					1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
+		fprintf(stdout, "\n");
 		}
 #endif
 #ifndef OPENSSL_NO_DSA
@@ -2590,12 +2705,18 @@ show_res:
 			j=0;
 			}
 		if(mr)
-			fprintf(stdout,"+F3:%u:%u:%f:%f\n",
-				k,dsa_bits[k],dsa_results[k][0],dsa_results[k][1]);
+			fprintf(stdout,"+F3:%u:%u:%f", k,dsa_bits[k],dsa_results[k][0]);
 		else
-			fprintf(stdout,"dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
-				dsa_bits[k],dsa_results[k][0],dsa_results[k][1],
-				1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
+			fprintf(stdout,"dsa %4u bits %8.6fs",dsa_bits[k],dsa_results[k][0]);
+		if (do_cpu)
+			fprintf(stdout, mr ? "/%d": "/%%%-3d", dsa_cpu_usage[k][0]);
+		fprintf(stdout, mr ? ":%f" : " %8.6fs", dsa_results[k][1]);
+		if (do_cpu)
+			fprintf(stdout, mr ? "/%d": "/%%%-3d", dsa_cpu_usage[k][1]);
+		if(!mr)
+			fprintf(stdout, " %8.1f %8.1f",
+					1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
+		fprintf(stdout, "\n");
 		}
 #endif
 #ifndef OPENSSL_NO_ECDSA
@@ -2720,8 +2841,10 @@ static void pkey_print_message(const cha
 
 static void print_result(int alg,int run_no,int count,double time_used)
 	{
-	BIO_printf(bio_err,mr ? "+R:%d:%s:%f\n"
-		   : "%d %s's in %.2fs\n",count,names[alg],time_used);
+	if (do_cpu)
+	    cpu_usage[alg][run_no] = calc_cpu();
+	BIO_printf(bio_err,mr ? "+R:%ld:%s:%f\n"
+		   : "%ld %s's in %.2fs\n",count,names[alg],time_used);
 	results[alg][run_no]=((double)count)/time_used*lengths[run_no];
 	}
 
@@ -2816,29 +2939,11 @@ static int do_multi(int multi)
 				p=buf+3;
 				alg=atoi(sstrsep(&p,sep));
 				sstrsep(&p,sep);
-				for(j=0 ; j < SIZE_NUM ; ++j)
+				for(j=0 ; j < SIZE_NUM ; ++j) {
+					if (do_cpu && strchr(p, '/'))
+						cpu_usage[alg][j] = atoi(strchr(p, '/') + 1);
 					results[alg][j]+=atof(sstrsep(&p,sep));
 				}
-			else if(!strncmp(buf,"+F2:",4))
-				{
-				int k;
-				double d;
-				
-				p=buf+4;
-				k=atoi(sstrsep(&p,sep));
-				sstrsep(&p,sep);
-
-				d=atof(sstrsep(&p,sep));
-				if(n)
-					rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
-				else
-					rsa_results[k][0]=d;
-
-				d=atof(sstrsep(&p,sep));
-				if(n)
-					rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
-				else
-					rsa_results[k][1]=d;
 				}
 			else if(!strncmp(buf,"+F2:",4))
 				{
@@ -2849,12 +2954,18 @@ static int do_multi(int multi)
 				k=atoi(sstrsep(&p,sep));
 				sstrsep(&p,sep);
 
+				/* before we move the token along */
+				if (do_cpu && strchr(p, '/'))
+					rsa_cpu_usage[k][0] = atoi(strchr(p, '/') + 1);
 				d=atof(sstrsep(&p,sep));
 				if(n)
 					rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
 				else
 					rsa_results[k][0]=d;
 
+				/* before we move the token along */
+				if (do_cpu && strchr(p, '/'))
+					rsa_cpu_usage[k][1] = atoi(strchr(p, '/') + 1);
 				d=atof(sstrsep(&p,sep));
 				if(n)
 					rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
@@ -2870,12 +2981,18 @@ static int do_multi(int multi)
 				k=atoi(sstrsep(&p,sep));
 				sstrsep(&p,sep);
 
+				/* before we move the token along */
+				if (do_cpu && strchr(p, '/'))
+					dsa_cpu_usage[k][0] = atoi(strchr(p, '/') + 1);
 				d=atof(sstrsep(&p,sep));
 				if(n)
 					dsa_results[k][0]=1/(1/dsa_results[k][0]+1/d);
 				else
 					dsa_results[k][0]=d;
 
+				/* before we move the token along */
+				if (do_cpu && strchr(p, '/'))
+					dsa_cpu_usage[k][1] = atoi(strchr(p, '/') + 1);
 				d=atof(sstrsep(&p,sep));
 				if(n)
 					dsa_results[k][1]=1/(1/dsa_results[k][1]+1/d);
--- a/crypto/cryptlib.h
+++ b/crypto/cryptlib.h
@@ -62,7 +62,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "e_os.h"
+#include <openssl/e_os.h>
 
 #ifdef OPENSSL_USE_APPLINK
 #define BIO_FLAGS_UPLINK 0x8000
--- a/crypto/engine/eng_all.c
+++ b/crypto/engine/eng_all.c
@@ -113,7 +113,7 @@ void ENGINE_load_builtin_engines(void)
 #endif
 	}
 
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 void ENGINE_setup_bsd_cryptodev(void) {
 	static int bsd_cryptodev_default_loaded = 0;
 	if (!bsd_cryptodev_default_loaded) {
--- a/crypto/engine/eng_cryptodev.c
+++ b/crypto/engine/eng_cryptodev.c
@@ -72,6 +72,16 @@ ENGINE_load_cryptodev(void)
 struct dev_crypto_state {
 	struct session_op d_sess;
 	int d_fd;
+
+#ifdef USE_CRYPTODEV_DIGESTS
+	char dummy_mac_key[20];
+
+	unsigned char digest_res[20];
+	char *mac_data;
+	int mac_len;
+
+	int copy;
+#endif
 };
 
 static u_int32_t cryptodev_asymfeat = 0;
@@ -79,9 +89,6 @@ static u_int32_t cryptodev_asymfeat = 0;
 static int get_asym_dev_crypto(void);
 static int open_dev_crypto(void);
 static int get_dev_crypto(void);
-static int cryptodev_max_iv(int cipher);
-static int cryptodev_key_length_valid(int cipher, int len);
-static int cipher_nid_to_cryptodev(int nid);
 static int get_cryptodev_ciphers(const int **cnids);
 /*static int get_cryptodev_digests(const int **cnids);*/
 static int cryptodev_usable_ciphers(const int **nids);
@@ -134,9 +141,12 @@ static struct {
 	int	ivmax;
 	int	keylen;
 } ciphers[] = {
+	{ CRYPTO_ARC4,			NID_rc4,		0,	16, },
 	{ CRYPTO_DES_CBC,		NID_des_cbc,		8,	 8, },
 	{ CRYPTO_3DES_CBC,		NID_des_ede3_cbc,	8,	24, },
 	{ CRYPTO_AES_CBC,		NID_aes_128_cbc,	16,	16, },
+	{ CRYPTO_AES_CBC,		NID_aes_192_cbc,	16,	24, },
+	{ CRYPTO_AES_CBC,		NID_aes_256_cbc,	16,	32, },
 	{ CRYPTO_BLF_CBC,		NID_bf_cbc,		8,	16, },
 	{ CRYPTO_CAST_CBC,		NID_cast5_cbc,		8,	16, },
 	{ CRYPTO_SKIPJACK_CBC,		NID_undef,		0,	 0, },
@@ -147,14 +157,16 @@ static struct {
 static struct {
 	int	id;
 	int	nid;
+	int 	keylen;
 } digests[] = {
-	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	},
-	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		},
-	{ CRYPTO_MD5_KPDK,		NID_undef,		},
-	{ CRYPTO_SHA1_KPDK,		NID_undef,		},
-	{ CRYPTO_MD5,			NID_md5,		},
-	{ CRYPTO_SHA1,			NID_undef,		},
-	{ 0,				NID_undef,		},
+	{ CRYPTO_MD5_HMAC,		NID_hmacWithMD5,	16},
+	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	20},
+	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		16/*?*/},
+	{ CRYPTO_MD5_KPDK,		NID_undef,		0},
+	{ CRYPTO_SHA1_KPDK,		NID_undef,		0},
+	{ CRYPTO_MD5,			NID_md5,		16},
+	{ CRYPTO_SHA1,			NID_sha1,		20},
+	{ 0,				NID_undef,		0},
 };
 #endif
 
@@ -182,10 +194,17 @@ open_dev_crypto(void)
 static int
 get_dev_crypto(void)
 {
-	int fd, retfd;
+	static int fd = -1;
+	int retfd;
 
-	if ((fd = open_dev_crypto()) == -1)
-		return (-1);
+	if (fd == -1) {
+		if ((fd = open_dev_crypto()) == -1)
+			return (-1);
+		if (fcntl(fd, F_SETFD, 1) == -1) {
+			close(fd);
+			return (-1);
+		}
+	}
 	if (ioctl(fd, CRIOGET, &retfd) == -1)
 		return (-1);
 
@@ -209,50 +228,6 @@ get_asym_dev_crypto(void)
 }
 
 /*
- * XXXX this needs to be set for each alg - and determined from
- * a running card.
- */
-static int
-cryptodev_max_iv(int cipher)
-{
-	int i;
-
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].id == cipher)
-			return (ciphers[i].ivmax);
-	return (0);
-}
-
-/*
- * XXXX this needs to be set for each alg - and determined from
- * a running card. For now, fake it out - but most of these
- * for real devices should return 1 for the supported key
- * sizes the device can handle.
- */
-static int
-cryptodev_key_length_valid(int cipher, int len)
-{
-	int i;
-
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].id == cipher)
-			return (ciphers[i].keylen == len);
-	return (0);
-}
-
-/* convert libcrypto nids to cryptodev */
-static int
-cipher_nid_to_cryptodev(int nid)
-{
-	int i;
-
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].nid == nid)
-			return (ciphers[i].id);
-	return (0);
-}
-
-/*
  * Find out what ciphers /dev/crypto will let us have a session for.
  * XXX note, that some of these openssl doesn't deal with yet!
  * returning them here is harmless, as long as we return NULL
@@ -270,7 +245,7 @@ get_cryptodev_ciphers(const int **cnids)
 		return (0);
 	}
 	memset(&sess, 0, sizeof(sess));
-	sess.key = (caddr_t)"123456781234567812345678";
+	sess.key = (caddr_t)"123456789abcdefghijklmno";
 
 	for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
 		if (ciphers[i].nid == NID_undef)
@@ -310,10 +285,12 @@ get_cryptodev_digests(const int **cnids)
 		return (0);
 	}
 	memset(&sess, 0, sizeof(sess));
+	sess.mackey = (caddr_t)"123456789abcdefghijklmno";
 	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
 		if (digests[i].nid == NID_undef)
 			continue;
 		sess.mac = digests[i].id;
+		sess.mackeylen = digests[i].keylen;
 		sess.cipher = 0;
 		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
 		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
@@ -360,6 +337,9 @@ cryptodev_usable_ciphers(const int **nid
 static int
 cryptodev_usable_digests(const int **nids)
 {
+#ifdef USE_CRYPTODEV_DIGESTS
+	return (get_cryptodev_digests(nids));
+#else
 	/*
 	 * XXXX just disable all digests for now, because it sucks.
 	 * we need a better way to decide this - i.e. I may not
@@ -374,6 +354,7 @@ cryptodev_usable_digests(const int **nid
 	 */
 	*nids = NULL;
 	return (0);
+#endif
 }
 
 static int
@@ -436,16 +417,20 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, 
 {
 	struct dev_crypto_state *state = ctx->cipher_data;
 	struct session_op *sess = &state->d_sess;
-	int cipher;
-
-	if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef)
-		return (0);
+	int cipher, i;
 
-	if (ctx->cipher->iv_len > cryptodev_max_iv(cipher))
-		return (0);
+	for (i = 0; ciphers[i].id; i++)
+		if (ctx->cipher->nid == ciphers[i].nid &&
+		    ctx->cipher->iv_len <= ciphers[i].ivmax &&
+		    ctx->key_len == ciphers[i].keylen) {
+			cipher = ciphers[i].id;
+			break;
+		}
 
-	if (!cryptodev_key_length_valid(cipher, ctx->key_len))
+	if (!ciphers[i].id) {
+		state->d_fd = -1;
 		return (0);
+	}
 
 	memset(sess, 0, sizeof(struct session_op));
 
@@ -505,6 +490,20 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
  * gets called when libcrypto requests a cipher NID.
  */
 
+/* RC4 */
+const EVP_CIPHER cryptodev_rc4 = {
+	NID_rc4,
+	1, 16, 0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	NULL,
+	NULL,
+	NULL
+};
+
 /* DES CBC EVP */
 const EVP_CIPHER cryptodev_des_cbc = {
 	NID_des_cbc,
@@ -572,6 +571,32 @@ const EVP_CIPHER cryptodev_aes_cbc = {
 	NULL
 };
 
+const EVP_CIPHER cryptodev_aes_192_cbc = {
+	NID_aes_192_cbc,
+	16, 24, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+const EVP_CIPHER cryptodev_aes_256_cbc = {
+	NID_aes_256_cbc,
+	16, 32, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
 /*
  * Registered by the ENGINE when used to find out how to deal with
  * a particular NID in the ENGINE. this says what we'll do at the
@@ -585,6 +610,9 @@ cryptodev_engine_ciphers(ENGINE *e, cons
 		return (cryptodev_usable_ciphers(nids));
 
 	switch (nid) {
+	case NID_rc4:
+		*cipher = &cryptodev_rc4;
+		break;
 	case NID_des_ede3_cbc:
 		*cipher = &cryptodev_3des_cbc;
 		break;
@@ -600,6 +628,12 @@ cryptodev_engine_ciphers(ENGINE *e, cons
 	case NID_aes_128_cbc:
 		*cipher = &cryptodev_aes_cbc;
 		break;
+	case NID_aes_192_cbc:
+		*cipher = &cryptodev_aes_192_cbc;
+		break;
+	case NID_aes_256_cbc:
+		*cipher = &cryptodev_aes_256_cbc;
+		break;
 	default:
 		*cipher = NULL;
 		break;
@@ -607,6 +641,234 @@ cryptodev_engine_ciphers(ENGINE *e, cons
 	return (*cipher != NULL);
 }
 
+
+#ifdef USE_CRYPTODEV_DIGESTS
+
+/* convert digest type to cryptodev */
+static int
+digest_nid_to_cryptodev(int nid)
+{
+	int i;
+
+	for (i = 0; digests[i].id; i++)
+		if (digests[i].nid == nid)
+			return (digests[i].id);
+	return (0);
+}
+
+
+static int
+digest_key_length(int nid)
+{
+	int i;
+
+	for (i = 0; digests[i].id; i++)
+		if (digests[i].nid == nid)
+			return digests[i].keylen;
+	return (0);
+}
+
+
+static int cryptodev_digest_init(EVP_MD_CTX *ctx)
+{
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+	int digest;
+
+	if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
+		fprintf(stderr, "cryptodev_digest_init: Can't get digest \n");
+		return (0);
+	}
+
+	memset(state, 0, sizeof(struct dev_crypto_state));
+
+	if ((state->d_fd = get_dev_crypto()) < 0) {
+		fprintf(stderr, "cryptodev_digest_init: Can't get Dev \n");
+		return (0);
+	}
+
+	sess->mackey = state->dummy_mac_key;
+	sess->mackeylen = digest_key_length(ctx->digest->type);
+	sess->mac = digest;
+
+	if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
+		close(state->d_fd);
+		state->d_fd = -1;
+		fprintf(stderr, "cryptodev_digest_init: Open session failed\n");
+		return (0);
+	}
+
+	return (1);
+}
+
+static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
+		size_t count)
+{
+	struct crypt_op cryp;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	if (!data || state->d_fd < 0) {
+		fprintf(stderr, "cryptodev_digest_update: illegal inputs \n");
+		return (0);
+	}
+
+	if (!count) {
+		return (0);
+	}
+
+	if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
+		/* if application doesn't support one buffer */
+		state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
+
+		if (!state->mac_data) {
+			fprintf(stderr, "cryptodev_digest_update: realloc failed\n");
+			return (0);
+		}
+
+		memcpy(state->mac_data + state->mac_len, data, count);
+   		state->mac_len += count;
+	
+		return (1);
+	}
+
+	memset(&cryp, 0, sizeof(cryp));
+
+	cryp.ses = sess->ses;
+	cryp.flags = 0;
+	cryp.len = count;
+	cryp.src = (caddr_t) data;
+	cryp.dst = NULL;
+	cryp.mac = state->digest_res;
+	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+		fprintf(stderr, "cryptodev_digest_update: digest failed\n");
+		return (0);
+	}
+	return (1);
+}
+
+
+static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	struct crypt_op cryp;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	int ret = 1;
+
+	if (!md || state->d_fd < 0) {
+		fprintf(stderr, "cryptodev_digest_final: illegal input\n");
+		return(0);
+	}
+
+	if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
+		/* if application doesn't support one buffer */
+		memset(&cryp, 0, sizeof(cryp));
+
+		cryp.ses = sess->ses;
+		cryp.flags = 0;
+		cryp.len = state->mac_len;
+		cryp.src = state->mac_data;
+		cryp.dst = NULL;
+		cryp.mac = md;
+
+		if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+			fprintf(stderr, "cryptodev_digest_final: digest failed\n");
+			return (0);
+		}
+
+		return 1;
+	}
+
+	memcpy(md, state->digest_res, ctx->digest->md_size);
+
+	return (ret);
+}
+
+
+static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
+{
+	int ret = 1;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	if (state->d_fd < 0) {
+		fprintf(stderr, "cryptodev_digest_cleanup: illegal input\n");
+		return (0);
+	}
+
+	if (state->mac_data) {
+		OPENSSL_free(state->mac_data);
+		state->mac_data = NULL;
+		state->mac_len = 0;
+	}
+
+	if (state->copy)
+		return 1;
+
+	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
+		fprintf(stderr, "cryptodev_digest_cleanup: failed to close session\n");
+		ret = 0;
+	} else {
+		ret = 1;
+	}
+	close(state->d_fd);	
+	state->d_fd = -1;
+
+	return (ret);
+}
+
+static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
+{
+	struct dev_crypto_state *fstate = from->md_data;
+	struct dev_crypto_state *dstate = to->md_data;
+
+	memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+
+	if (fstate->mac_len != 0) {
+		dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+		memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+	}
+
+	dstate->copy = 1;
+
+	return 1;
+}
+
+
+const EVP_MD cryptodev_sha1 = {
+	NID_sha1,
+	NID_undef, 
+	SHA_DIGEST_LENGTH, 
+	EVP_MD_FLAG_ONESHOT,
+	cryptodev_digest_init,
+	cryptodev_digest_update,
+	cryptodev_digest_final,
+	cryptodev_digest_copy,
+	cryptodev_digest_cleanup,
+	EVP_PKEY_NULL_method,
+	SHA_CBLOCK,
+	sizeof(struct dev_crypto_state),
+};
+
+const EVP_MD cryptodev_md5 = {
+	NID_md5,
+	NID_undef, 
+	16 /* MD5_DIGEST_LENGTH */, 
+	EVP_MD_FLAG_ONESHOT,
+	cryptodev_digest_init,
+	cryptodev_digest_update,
+	cryptodev_digest_final,
+	cryptodev_digest_copy,
+	cryptodev_digest_cleanup,
+	EVP_PKEY_NULL_method,
+	64 /* MD5_CBLOCK */,
+	sizeof(struct dev_crypto_state),
+};
+
+#endif /* USE_CRYPTODEV_DIGESTS */
+
+
 static int
 cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
     const int **nids, int nid)
@@ -615,10 +877,15 @@ cryptodev_engine_digests(ENGINE *e, cons
 		return (cryptodev_usable_digests(nids));
 
 	switch (nid) {
+#ifdef USE_CRYPTODEV_DIGESTS
 	case NID_md5:
-		*digest = NULL; /* need to make a clean md5 critter */
+		*digest = &cryptodev_md5; 
 		break;
+	case NID_sha1:
+		*digest = &cryptodev_sha1;
+ 		break;
 	default:
+#endif /* USE_CRYPTODEV_DIGESTS */
 		*digest = NULL;
 		break;
 	}
@@ -646,6 +913,7 @@ bn2crparam(const BIGNUM *a, struct crpar
 	b = malloc(bytes);
 	if (b == NULL)
 		return (1);
+	memset(b, 0, bytes);
 
 	crp->crp_p = (char *)b;
 	crp->crp_nbits = bits;
@@ -690,7 +958,7 @@ zapparams(struct crypt_kop *kop)
 {
 	int i;
 
-	for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) {
+	for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
 		if (kop->crk_param[i].crp_p)
 			free(kop->crk_param[i].crp_p);
 		kop->crk_param[i].crp_p = NULL;
@@ -776,7 +1044,6 @@ static int
 cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
 {
 	int r;
-
 	r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
 	return (r);
 }
@@ -920,6 +1187,9 @@ cryptodev_dsa_do_sign(const unsigned cha
 		const DSA_METHOD *meth = DSA_OpenSSL();
 		BN_free(r);
 		BN_free(s);
+		fprintf(stderr, "cryptodev_asym: CRK_DSA_SIGN %s failed, "
+			"Running in software\n", errno==kop.crk_status ?
+			"hardware operation" : "asym process");
 		dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
 	}
 err:
@@ -961,6 +1231,9 @@ cryptodev_dsa_verify(const unsigned char
 	} else {
 		const DSA_METHOD *meth = DSA_OpenSSL();
 
+		fprintf(stderr, "cryptodev_asym: CRK_DSA_VERIFY %s failed, "
+			"Running in software\n", errno==kop.crk_status ?
+			"hardware operation" : "asym process");
 		dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
 	}
 err:
@@ -994,8 +1267,8 @@ static int
 cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
 {
 	struct crypt_kop kop;
-	int dhret = 1;
-	int fd, keylen;
+	int dhret = -1;
+	int fd, keybits;
 
 	if ((fd = get_asym_dev_crypto()) < 0) {
 		const DH_METHOD *meth = DH_OpenSSL();
@@ -1003,7 +1276,7 @@ cryptodev_dh_compute_key(unsigned char *
 		return ((meth->compute_key)(key, pub_key, dh));
 	}
 
-	keylen = BN_num_bits(dh->p);
+	keybits = BN_num_bits(dh->p);
 
 	memset(&kop, 0, sizeof kop);
 	kop.crk_op = CRK_DH_COMPUTE_KEY;
@@ -1018,14 +1291,18 @@ cryptodev_dh_compute_key(unsigned char *
 	kop.crk_iparams = 3;
 
 	kop.crk_param[3].crp_p = (char *)key;
-	kop.crk_param[3].crp_nbits = keylen * 8;
+	kop.crk_param[3].crp_nbits = keybits;
 	kop.crk_oparams = 1;
 
 	if (ioctl(fd, CIOCKEY, &kop) == -1) {
 		const DH_METHOD *meth = DH_OpenSSL();
 
+		fprintf(stderr, "cryptodev_asym: CRK_DH_COMPUTE_KEY %s failed, "
+			"Running in software\n", errno==kop.crk_status ?
+			"hardware operation" : "asym process");
 		dhret = (meth->compute_key)(key, pub_key, dh);
-	}
+	} else
+		dhret = (keybits + 7) / 8;
 err:
 	kop.crk_param[3].crp_p = NULL;
 	zapparams(&kop);
--- a/crypto/engine/engine.h
+++ b/crypto/engine/engine.h
@@ -705,7 +705,7 @@ typedef int (*dynamic_bind_engine)(ENGIN
  * values. */
 void *ENGINE_get_static_state(void);
 
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 void ENGINE_setup_bsd_cryptodev(void);
 #endif
 
--- a/crypto/evp/c_all.c
+++ b/crypto/evp/c_all.c
@@ -83,7 +83,7 @@ void OPENSSL_add_all_algorithms_noconf(v
 	OpenSSL_add_all_ciphers();
 	OpenSSL_add_all_digests();
 #ifndef OPENSSL_NO_ENGINE
-# if defined(__OpenBSD__) || defined(__FreeBSD__)
+# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 	ENGINE_setup_bsd_cryptodev();
 # endif
 #endif
--- a/crypto/evp/c_alld.c
+++ b/crypto/evp/c_alld.c
@@ -78,7 +78,7 @@ void OpenSSL_add_all_digests(void)
 	EVP_add_digest(EVP_dss());
 #endif
 #endif
-#ifndef OPENSSL_NO_SHA
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
 	EVP_add_digest(EVP_sha1());
 	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
 	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
--- a/engines/Makefile
+++ b/engines/Makefile
@@ -97,6 +97,7 @@ install:
 			( echo installing $$l; \
 			  if [ "$(PLATFORM)" != "Cygwin" ]; then \
 				case "$(CFLAGS)" in \
+				*OPENSSL_NO_HW*)	continue;;	\
 				*DSO_DLFCN*)	sfx="so";;	\
 				*DSO_DL*)	sfx="sl";;	\
 				*)		sfx="bad";;	\