summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.c (renamed from usr/src/cmd/cmd-inet/usr.bin/pppd/md4.c)0
-rw-r--r--deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.h (renamed from usr/src/cmd/cmd-inet/usr.bin/pppd/md4.h)0
-rw-r--r--deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.c (renamed from usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.c)0
-rw-r--r--deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.h (renamed from usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.h)0
-rw-r--r--deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1_consts.h (renamed from usr/src/cmd/cmd-inet/usr.bin/pppd/sha1_consts.h)0
-rw-r--r--deleted_files/usr/src/common/net/wanboot/crypt/sha1.c (renamed from usr/src/common/net/wanboot/crypt/sha1.c)0
-rw-r--r--deleted_files/usr/src/lib/libmd5/spec/Makefile (renamed from usr/src/lib/libmd5/spec/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5/spec/Makefile.targ (renamed from usr/src/lib/libmd5/spec/Makefile.targ)0
-rw-r--r--deleted_files/usr/src/lib/libmd5/spec/amd64/Makefile (renamed from usr/src/lib/libmd5/spec/amd64/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5/spec/i386/Makefile (renamed from usr/src/lib/libmd5/spec/i386/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5/spec/md5.spec (renamed from usr/src/lib/libmd5/spec/md5.spec)0
-rw-r--r--deleted_files/usr/src/lib/libmd5/spec/sparc/Makefile (renamed from usr/src/lib/libmd5/spec/sparc/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5/spec/sparcv9/Makefile (renamed from usr/src/lib/libmd5/spec/sparcv9/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5/spec/versions (renamed from usr/src/lib/libmd5/spec/versions)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/Makefile (renamed from usr/src/lib/libmd5_psr/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/Makefile.com (renamed from usr/src/lib/libmd5_psr/Makefile.com)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/Makefile.targ (renamed from usr/src/lib/libmd5_psr/Makefile.targ)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/inc.flg (renamed from usr/src/lib/libmd5_psr/inc.flg)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/sparc/Makefile (renamed from usr/src/lib/libmd5_psr/sparc/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/sparc/sun4u/Makefile (renamed from usr/src/lib/libmd5_psr/sparc/sun4u/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/sparcv9/Makefile (renamed from usr/src/lib/libmd5_psr/sparcv9/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/sparcv9/sun4u/Makefile (renamed from usr/src/lib/libmd5_psr/sparcv9/sun4u/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/Makefile (renamed from usr/src/lib/libmd5_psr/spec/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/Makefile.com (renamed from usr/src/lib/libmd5_psr/spec/Makefile.com)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/sparc/Makefile (renamed from usr/src/lib/libmd5_psr/spec/sparc/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/sparc/sun4u/Makefile (renamed from usr/src/lib/libmd5_psr/spec/sparc/sun4u/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/sparc/versions-sun4u (renamed from usr/src/lib/libmd5_psr/spec/sparc/versions-sun4u)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/Makefile (renamed from usr/src/lib/libmd5_psr/spec/sparcv9/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/md_psr-sun4u.spec (renamed from usr/src/lib/libmd5_psr/spec/sparcv9/md5_psr-sun4u.spec)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/sun4u/Makefile (renamed from usr/src/lib/libmd5_psr/spec/sparcv9/sun4u/Makefile)0
-rw-r--r--deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/versions-sun4u (renamed from usr/src/lib/libmd5_psr/spec/sparcv9/versions-sun4u)0
-rw-r--r--deleted_files/usr/src/lib/libmd_psr/spec/sparc/md_psr-sun4u.spec (renamed from usr/src/lib/libmd5_psr/spec/sparc/md5_psr-sun4u.spec)0
-rw-r--r--usr/src/Makefile.lint2
-rw-r--r--usr/src/Targetdirs11
-rw-r--r--usr/src/cmd/bart/Makefile11
-rw-r--r--usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile11
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/in.routed/Makefile4
-rw-r--r--usr/src/cmd/ipf/tools/Makefile.tools6
-rw-r--r--usr/src/cmd/volmgt/vold/Makefile11
-rw-r--r--usr/src/cmd/xntpd/Makefile.cmd4
-rw-r--r--usr/src/common/crypto/md4/md4.c (renamed from usr/src/cmd/volmgt/vold/vold_md4.c)72
-rw-r--r--usr/src/common/crypto/md5/md5.c1537
-rw-r--r--usr/src/common/crypto/md5/md5_byteswap.h37
-rw-r--r--usr/src/common/crypto/sha1/sha1.c2016
-rw-r--r--usr/src/common/crypto/sha2/sha2.c1838
-rw-r--r--usr/src/head/Makefile8
-rw-r--r--usr/src/lib/Makefile13
-rw-r--r--usr/src/lib/crypt_modules/bsdmd5/Makefile.com9
-rw-r--r--usr/src/lib/crypt_modules/sunmd5/Makefile.com9
-rw-r--r--usr/src/lib/libbsm/Makefile.com2
-rw-r--r--usr/src/lib/libinetsvc/Makefile.com9
-rw-r--r--usr/src/lib/libldap4/Makefile.com4
-rw-r--r--usr/src/lib/libldap5/Makefile.com2
-rw-r--r--usr/src/lib/libmd/Makefile64
-rw-r--r--usr/src/lib/libmd/Makefile.com124
-rw-r--r--usr/src/lib/libmd/amd64/Makefile33
-rw-r--r--usr/src/lib/libmd/common/llib-lmd34
-rw-r--r--usr/src/lib/libmd/common/md4.h (renamed from usr/src/cmd/volmgt/vold/md4.h)10
-rw-r--r--usr/src/lib/libmd/common/md5.h (renamed from usr/src/head/md5.h)4
-rw-r--r--usr/src/lib/libmd/common/sha1.h34
-rw-r--r--usr/src/lib/libmd/common/sha2.h34
-rw-r--r--usr/src/lib/libmd/i386/Makefile31
-rw-r--r--usr/src/lib/libmd/inc.flg31
-rw-r--r--usr/src/lib/libmd/sparc/Makefile32
-rw-r--r--usr/src/lib/libmd/sparcv9/Makefile33
-rw-r--r--usr/src/lib/libmd/spec/Makefile29
-rw-r--r--usr/src/lib/libmd/spec/Makefile.targ32
-rw-r--r--usr/src/lib/libmd/spec/amd64/Makefile35
-rw-r--r--usr/src/lib/libmd/spec/i386/Makefile34
-rw-r--r--usr/src/lib/libmd/spec/md.spec192
-rw-r--r--usr/src/lib/libmd/spec/sparc/Makefile32
-rw-r--r--usr/src/lib/libmd/spec/sparcv9/Makefile35
-rw-r--r--usr/src/lib/libmd/spec/versions37
-rw-r--r--usr/src/lib/libmd/sun4u/Makefile46
-rw-r--r--usr/src/lib/libmd/sun4u/Makefile.com42
-rw-r--r--usr/src/lib/libmd/sun4u/Makefile.links66
-rw-r--r--usr/src/lib/libmd/sun4u/sparc/Makefile58
-rw-r--r--usr/src/lib/libmd/sun4u/sparc/mapfile37
-rw-r--r--usr/src/lib/libmd/sun4u/sparcv9/Makefile60
-rw-r--r--usr/src/lib/libmd/sun4u/sparcv9/mapfile37
-rw-r--r--usr/src/lib/libmd/sun4v/Makefile46
-rw-r--r--usr/src/lib/libmd/sun4v/Makefile.com42
-rw-r--r--usr/src/lib/libmd/sun4v/Makefile.links32
-rw-r--r--usr/src/lib/libmd/sun4v/sparc/Makefile58
-rw-r--r--usr/src/lib/libmd/sun4v/sparc/mapfile33
-rw-r--r--usr/src/lib/libmd/sun4v/sparcv9/Makefile60
-rw-r--r--usr/src/lib/libmd/sun4v/sparcv9/mapfile33
-rw-r--r--usr/src/lib/libmd5/Makefile22
-rw-r--r--usr/src/lib/libmd5/Makefile.com55
-rw-r--r--usr/src/lib/libmd5/amd64/Makefile12
-rw-r--r--usr/src/lib/libmd5/common/llib-lmd5 (renamed from usr/src/lib/libmd5/llib-lmd5)15
-rw-r--r--usr/src/lib/libmd5/common/mapfile-vers42
-rw-r--r--usr/src/lib/libmd5/sparc/Makefile8
-rw-r--r--usr/src/lib/libmd5/sparcv9/Makefile10
-rw-r--r--usr/src/lib/libnsl/Makefile.com4
-rw-r--r--usr/src/lib/libresolv2/dnssafe/Makefile.com2
-rw-r--r--usr/src/lib/librt/Makefile.com7
-rw-r--r--usr/src/lib/librt/common/pos4obj.c10
-rw-r--r--usr/src/lib/libsasl/Makefile.com4
-rw-r--r--usr/src/lib/libwanbootutil/Makefile.com10
-rw-r--r--usr/src/lib/libwanbootutil/spec/wanbootutil.spec19
-rw-r--r--usr/src/lib/pkcs11/Makefile.softtoken.com13
-rw-r--r--usr/src/lib/pkcs11/Makefile.softtoken.sparc14
-rw-r--r--usr/src/lib/pkcs11/Makefile.softtoken.sparcv914
-rw-r--r--usr/src/pkgdefs/SUNWarcr/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWarcr/prototype_i3861
-rw-r--r--usr/src/pkgdefs/SUNWarcr/prototype_sparc1
-rw-r--r--usr/src/pkgdefs/SUNWcar.u/prototype_com143
-rw-r--r--usr/src/pkgdefs/SUNWcar.v/prototype_com7
-rw-r--r--usr/src/pkgdefs/SUNWcsl/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWcsl/prototype_i3862
-rw-r--r--usr/src/pkgdefs/SUNWcsl/prototype_sparc2
-rw-r--r--usr/src/pkgdefs/SUNWcslr/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWcslr/prototype_i3862
-rw-r--r--usr/src/pkgdefs/SUNWcslr/prototype_sparc2
-rw-r--r--usr/src/pkgdefs/SUNWhea/prototype_com5
-rw-r--r--usr/src/stand/lib/Makefile.targ13
-rw-r--r--usr/src/stand/lib/scrypt/Makefile16
-rw-r--r--usr/src/uts/common/Makefile.files6
-rw-r--r--usr/src/uts/common/crypto/io/md5_mod.c1500
-rw-r--r--usr/src/uts/common/crypto/io/sha1_mod.c1471
-rw-r--r--usr/src/uts/common/crypto/io/sha2_mod.c1618
-rw-r--r--usr/src/uts/common/sys/sha1.h11
-rw-r--r--usr/src/uts/common/sys/sha2.h88
-rw-r--r--usr/src/uts/sun4v/md5/Makefile12
125 files changed, 6940 insertions, 5383 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.c b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.c
index fc09a02cad..fc09a02cad 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.c
+++ b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.c
diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.h b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.h
index 3f7ef15c65..3f7ef15c65 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.h
+++ b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/md4.h
diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.c b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.c
index 64e2dbae64..64e2dbae64 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.c
+++ b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.c
diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.h b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.h
index af6c511b92..af6c511b92 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.h
+++ b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1.h
diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1_consts.h b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1_consts.h
index 126e245498..126e245498 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1_consts.h
+++ b/deleted_files/usr/src/cmd/cmd-inet/usr.bin/pppd/sha1_consts.h
diff --git a/usr/src/common/net/wanboot/crypt/sha1.c b/deleted_files/usr/src/common/net/wanboot/crypt/sha1.c
index 10d285eb48..10d285eb48 100644
--- a/usr/src/common/net/wanboot/crypt/sha1.c
+++ b/deleted_files/usr/src/common/net/wanboot/crypt/sha1.c
diff --git a/usr/src/lib/libmd5/spec/Makefile b/deleted_files/usr/src/lib/libmd5/spec/Makefile
index 777f118831..777f118831 100644
--- a/usr/src/lib/libmd5/spec/Makefile
+++ b/deleted_files/usr/src/lib/libmd5/spec/Makefile
diff --git a/usr/src/lib/libmd5/spec/Makefile.targ b/deleted_files/usr/src/lib/libmd5/spec/Makefile.targ
index 50c69d947c..50c69d947c 100644
--- a/usr/src/lib/libmd5/spec/Makefile.targ
+++ b/deleted_files/usr/src/lib/libmd5/spec/Makefile.targ
diff --git a/usr/src/lib/libmd5/spec/amd64/Makefile b/deleted_files/usr/src/lib/libmd5/spec/amd64/Makefile
index b2e036a827..b2e036a827 100644
--- a/usr/src/lib/libmd5/spec/amd64/Makefile
+++ b/deleted_files/usr/src/lib/libmd5/spec/amd64/Makefile
diff --git a/usr/src/lib/libmd5/spec/i386/Makefile b/deleted_files/usr/src/lib/libmd5/spec/i386/Makefile
index 69ffa17e22..69ffa17e22 100644
--- a/usr/src/lib/libmd5/spec/i386/Makefile
+++ b/deleted_files/usr/src/lib/libmd5/spec/i386/Makefile
diff --git a/usr/src/lib/libmd5/spec/md5.spec b/deleted_files/usr/src/lib/libmd5/spec/md5.spec
index ee07dcc33a..ee07dcc33a 100644
--- a/usr/src/lib/libmd5/spec/md5.spec
+++ b/deleted_files/usr/src/lib/libmd5/spec/md5.spec
diff --git a/usr/src/lib/libmd5/spec/sparc/Makefile b/deleted_files/usr/src/lib/libmd5/spec/sparc/Makefile
index a88d8c12fe..a88d8c12fe 100644
--- a/usr/src/lib/libmd5/spec/sparc/Makefile
+++ b/deleted_files/usr/src/lib/libmd5/spec/sparc/Makefile
diff --git a/usr/src/lib/libmd5/spec/sparcv9/Makefile b/deleted_files/usr/src/lib/libmd5/spec/sparcv9/Makefile
index 1227c98be0..1227c98be0 100644
--- a/usr/src/lib/libmd5/spec/sparcv9/Makefile
+++ b/deleted_files/usr/src/lib/libmd5/spec/sparcv9/Makefile
diff --git a/usr/src/lib/libmd5/spec/versions b/deleted_files/usr/src/lib/libmd5/spec/versions
index f7955484e7..f7955484e7 100644
--- a/usr/src/lib/libmd5/spec/versions
+++ b/deleted_files/usr/src/lib/libmd5/spec/versions
diff --git a/usr/src/lib/libmd5_psr/Makefile b/deleted_files/usr/src/lib/libmd5_psr/Makefile
index 0cda9bbeb8..0cda9bbeb8 100644
--- a/usr/src/lib/libmd5_psr/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/Makefile
diff --git a/usr/src/lib/libmd5_psr/Makefile.com b/deleted_files/usr/src/lib/libmd5_psr/Makefile.com
index d3a483fea3..d3a483fea3 100644
--- a/usr/src/lib/libmd5_psr/Makefile.com
+++ b/deleted_files/usr/src/lib/libmd5_psr/Makefile.com
diff --git a/usr/src/lib/libmd5_psr/Makefile.targ b/deleted_files/usr/src/lib/libmd5_psr/Makefile.targ
index f5a9f0b101..f5a9f0b101 100644
--- a/usr/src/lib/libmd5_psr/Makefile.targ
+++ b/deleted_files/usr/src/lib/libmd5_psr/Makefile.targ
diff --git a/usr/src/lib/libmd5_psr/inc.flg b/deleted_files/usr/src/lib/libmd5_psr/inc.flg
index bee518812f..bee518812f 100644
--- a/usr/src/lib/libmd5_psr/inc.flg
+++ b/deleted_files/usr/src/lib/libmd5_psr/inc.flg
diff --git a/usr/src/lib/libmd5_psr/sparc/Makefile b/deleted_files/usr/src/lib/libmd5_psr/sparc/Makefile
index 7d463c28db..7d463c28db 100644
--- a/usr/src/lib/libmd5_psr/sparc/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/sparc/Makefile
diff --git a/usr/src/lib/libmd5_psr/sparc/sun4u/Makefile b/deleted_files/usr/src/lib/libmd5_psr/sparc/sun4u/Makefile
index 49548d743c..49548d743c 100644
--- a/usr/src/lib/libmd5_psr/sparc/sun4u/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/sparc/sun4u/Makefile
diff --git a/usr/src/lib/libmd5_psr/sparcv9/Makefile b/deleted_files/usr/src/lib/libmd5_psr/sparcv9/Makefile
index a6a6614cb2..a6a6614cb2 100644
--- a/usr/src/lib/libmd5_psr/sparcv9/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/sparcv9/Makefile
diff --git a/usr/src/lib/libmd5_psr/sparcv9/sun4u/Makefile b/deleted_files/usr/src/lib/libmd5_psr/sparcv9/sun4u/Makefile
index c0745d5e11..c0745d5e11 100644
--- a/usr/src/lib/libmd5_psr/sparcv9/sun4u/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/sparcv9/sun4u/Makefile
diff --git a/usr/src/lib/libmd5_psr/spec/Makefile b/deleted_files/usr/src/lib/libmd5_psr/spec/Makefile
index cec6b0047f..cec6b0047f 100644
--- a/usr/src/lib/libmd5_psr/spec/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/Makefile
diff --git a/usr/src/lib/libmd5_psr/spec/Makefile.com b/deleted_files/usr/src/lib/libmd5_psr/spec/Makefile.com
index 1c1d9a915b..1c1d9a915b 100644
--- a/usr/src/lib/libmd5_psr/spec/Makefile.com
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/Makefile.com
diff --git a/usr/src/lib/libmd5_psr/spec/sparc/Makefile b/deleted_files/usr/src/lib/libmd5_psr/spec/sparc/Makefile
index 71c74ea5a9..71c74ea5a9 100644
--- a/usr/src/lib/libmd5_psr/spec/sparc/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/sparc/Makefile
diff --git a/usr/src/lib/libmd5_psr/spec/sparc/sun4u/Makefile b/deleted_files/usr/src/lib/libmd5_psr/spec/sparc/sun4u/Makefile
index d2f2c3bf15..d2f2c3bf15 100644
--- a/usr/src/lib/libmd5_psr/spec/sparc/sun4u/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/sparc/sun4u/Makefile
diff --git a/usr/src/lib/libmd5_psr/spec/sparc/versions-sun4u b/deleted_files/usr/src/lib/libmd5_psr/spec/sparc/versions-sun4u
index 7f8676bc03..7f8676bc03 100644
--- a/usr/src/lib/libmd5_psr/spec/sparc/versions-sun4u
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/sparc/versions-sun4u
diff --git a/usr/src/lib/libmd5_psr/spec/sparcv9/Makefile b/deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/Makefile
index ca621bd3dd..ca621bd3dd 100644
--- a/usr/src/lib/libmd5_psr/spec/sparcv9/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/Makefile
diff --git a/usr/src/lib/libmd5_psr/spec/sparcv9/md5_psr-sun4u.spec b/deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/md_psr-sun4u.spec
index 1f0c22c8bf..1f0c22c8bf 100644
--- a/usr/src/lib/libmd5_psr/spec/sparcv9/md5_psr-sun4u.spec
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/md_psr-sun4u.spec
diff --git a/usr/src/lib/libmd5_psr/spec/sparcv9/sun4u/Makefile b/deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/sun4u/Makefile
index e2010777b2..e2010777b2 100644
--- a/usr/src/lib/libmd5_psr/spec/sparcv9/sun4u/Makefile
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/sun4u/Makefile
diff --git a/usr/src/lib/libmd5_psr/spec/sparcv9/versions-sun4u b/deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/versions-sun4u
index 463cbb78ac..463cbb78ac 100644
--- a/usr/src/lib/libmd5_psr/spec/sparcv9/versions-sun4u
+++ b/deleted_files/usr/src/lib/libmd5_psr/spec/sparcv9/versions-sun4u
diff --git a/usr/src/lib/libmd5_psr/spec/sparc/md5_psr-sun4u.spec b/deleted_files/usr/src/lib/libmd_psr/spec/sparc/md_psr-sun4u.spec
index aa169d0404..aa169d0404 100644
--- a/usr/src/lib/libmd5_psr/spec/sparc/md5_psr-sun4u.spec
+++ b/deleted_files/usr/src/lib/libmd_psr/spec/sparc/md_psr-sun4u.spec
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint
index 39dcec77c2..92f09d2bec 100644
--- a/usr/src/Makefile.lint
+++ b/usr/src/Makefile.lint
@@ -326,7 +326,7 @@ COMMON_SUBDIRS = \
lib/liblm \
lib/libmacadm \
lib/libmalloc \
- lib/libmd5 \
+ lib/libmd \
lib/libmp \
lib/libnsl \
lib/libnvpair \
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index 27473441b8..d1e77e3cff 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -201,6 +201,7 @@ ROOT.BIN= \
/usr/include/libmilter \
/usr/include/sasl \
/usr/include/tsol \
+ /usr/include/security \
/usr/lib \
/usr/lib/abi \
/usr/lib/class \
@@ -810,6 +811,8 @@ $(ROOT)/usr/lib/libintl.so:= REALPATH=../../lib/libintl.so.1
$(ROOT)/usr/lib/libkstat.so.1:= REALPATH=../../lib/libkstat.so.1
$(ROOT)/usr/lib/libkstat.so:= REALPATH=../../lib/libkstat.so.1
$(ROOT)/usr/lib/liblddbg.so.4:= REALPATH=../../lib/liblddbg.so.4
+$(ROOT)/usr/lib/libmd.so.1:= REALPATH=../../lib/libmd.so.1
+$(ROOT)/usr/lib/libmd.so:= REALPATH=../../lib/libmd.so.1
$(ROOT)/usr/lib/libmd5.so.1:= REALPATH=../../lib/libmd5.so.1
$(ROOT)/usr/lib/libmd5.so:= REALPATH=../../lib/libmd5.so.1
$(ROOT)/usr/lib/libmeta.so.1:= REALPATH=../../lib/libmeta.so.1
@@ -1080,6 +1083,10 @@ $(ROOT)/usr/lib/$(MACH64)/libkstat.so:= \
REALPATH=../../../lib/$(MACH64)/libkstat.so.1
$(ROOT)/usr/lib/$(MACH64)/liblddbg.so.4:= \
REALPATH=../../../lib/$(MACH64)/liblddbg.so.4
+$(ROOT)/usr/lib/$(MACH64)/libmd.so.1:= \
+ REALPATH=../../../lib/$(MACH64)/libmd.so.1
+$(ROOT)/usr/lib/$(MACH64)/libmd.so:= \
+ REALPATH=../../../lib/$(MACH64)/libmd.so.1
$(ROOT)/usr/lib/$(MACH64)/libmd5.so.1:= \
REALPATH=../../../lib/$(MACH64)/libmd5.so.1
$(ROOT)/usr/lib/$(MACH64)/libmd5.so:= \
@@ -1382,6 +1389,8 @@ SYM.USRLIB= \
/usr/lib/libkstat.so \
/usr/lib/libkstat.so.1 \
/usr/lib/liblddbg.so.4 \
+ /usr/lib/libmd.so \
+ /usr/lib/libmd.so.1 \
/usr/lib/libmd5.so \
/usr/lib/libmd5.so.1 \
/usr/lib/libmeta.so \
@@ -1615,6 +1624,8 @@ SYM.USRLIB64= \
/usr/lib/$(MACH64)/libkstat.so \
/usr/lib/$(MACH64)/libkstat.so.1 \
/usr/lib/$(MACH64)/liblddbg.so.4 \
+ /usr/lib/$(MACH64)/libmd.so \
+ /usr/lib/$(MACH64)/libmd.so.1 \
/usr/lib/$(MACH64)/libmd5.so \
/usr/lib/$(MACH64)/libmd5.so.1 \
/usr/lib/$(MACH64)/libmp.so \
diff --git a/usr/src/cmd/bart/Makefile b/usr/src/cmd/bart/Makefile
index da68a0417f..eee36ba33e 100644
--- a/usr/src/cmd/bart/Makefile
+++ b/usr/src/cmd/bart/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,8 +21,8 @@
#
#pragma ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
PROG= bart
SRCS= rules.c create.c compare.c main.c lutbl.c
@@ -31,7 +30,7 @@ OBJS= rules.o create.o compare.o main.o lutbl.o
BART= bart
include ../Makefile.cmd
-LDLIBS += -lsec -lmd5
+LDLIBS += -lsec -lmd
#
# for messaging catalog
diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile b/usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile
index 59d95063e2..0946e38299 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile
@@ -1,7 +1,7 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# cmd/cmd-inet/usr.bin/pppd/Makefile
@@ -24,7 +24,7 @@ clean:= TARGET= clean
clobber:= TARGET= clobber
lint:= TARGET= lint
-LDLIBS += -lpam -lmd5 -lsocket -lnsl
+LDLIBS += -lpam -lmd -lsocket -lnsl
#
# We need absolute path to /etc/ppp/plugins and /usr/lib/inet/ppp, not
@@ -48,16 +48,15 @@ all: $(PROG) $(SUBDIRS)
CPPFLAGS += -DHAVE_CRYPT_H -DUSE_CRYPT
CPPFLAGS += -DCHAPMS -DMSLANMAN
CPPFLAGS += -DCHAPMSV2
-OBJS += chap_ms.o md4.o sha1.o
+OBJS += chap_ms.o
EXOBJS += mschap_test.o
CLOBBERFILES += mschap_test
# This is used *only* for testing the portability of the libraries
# required for MS-CHAPv1. It is not needed in any normal system and
# is not built by default.
-mschap_test: mschap_test.o chap_ms.o md4.o sha1.o
- $(LINK.c) -o mschap_test mschap_test.o chap_ms.o md4.o sha1.o \
- $(LDFLAGS)
+mschap_test: mschap_test.o chap_ms.o
+ $(LINK.c) -o mschap_test mschap_test.o chap_ms.o $(LDFLAGS)
@echo "Run with 'mschap_test 00000000000000000000000000000000 hello'"
@echo
@echo "Output should be:"
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.routed/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/in.routed/Makefile
index 8d1cf19e06..e225fb1df9 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.routed/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.routed/Makefile
@@ -1,7 +1,7 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -33,7 +33,7 @@ LINTFLAGS += -erroff=E_FUNC_DECL_VAR_ARG2 -erroff=E_INCONS_VAL_TYPE_DECL2 \
CPPFLAGS += $(_D_XOPEN_EXTN)
CFLAGS += $(CCVERBOSE)
-LDLIBS += -lxnet -lmd5 -lsocket
+LDLIBS += -lxnet -lmd -lsocket
CLEAN_FILES += $(ROUTEDOBJS) $(RTQUERYOBJS)
CLOBBERFILES += $(ROUTEDPROG) $(RTQUERYPROG)
#
diff --git a/usr/src/cmd/ipf/tools/Makefile.tools b/usr/src/cmd/ipf/tools/Makefile.tools
index ec46c5d658..c4cd838a04 100644
--- a/usr/src/cmd/ipf/tools/Makefile.tools
+++ b/usr/src/cmd/ipf/tools/Makefile.tools
@@ -1,9 +1,9 @@
#
-# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
-#pragma ident "%Z%%M% %I% %E% SMI"
+# ident "%Z%%M% %I% %E% SMI"
#
PROG= ipf ipfs ipmon ipnat ippool ipfstat
@@ -44,7 +44,7 @@ ipfstat.o := CPPFLAGS += -DSTATETOP
ipfstat := LDLIBS += -lcurses
ipf := LDLIBS += -lsocket -lnsl
-ipftest := LDLIBS += -lsocket -lnsl -lmd5
+ipftest := LDLIBS += -lsocket -lnsl -lmd
ipfstat := LDLIBS += -lsocket -lnsl -lkvm -lelf
ipmon := LDLIBS += -lsocket -lnsl
ipnat := LDLIBS += -lsocket -lnsl -lkvm -lelf
diff --git a/usr/src/cmd/volmgt/vold/Makefile b/usr/src/cmd/volmgt/vold/Makefile
index 938c639509..91fdb270eb 100644
--- a/usr/src/cmd/volmgt/vold/Makefile
+++ b/usr/src/cmd/volmgt/vold/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -41,7 +40,7 @@ SED= sed
OBJS= nfs_server.o nfs_trace.o vold_err.o vold_main.o vold_proc.o \
vold_node.o vold_util.o vold_dev.o vold_config.o vold_vol.o \
vold_label.o vold_db.o vold_path.o vold_props.o vold_action.o \
- vold_obj.o vold_md4.o vold_mnt.o medium.o partition.o \
+ vold_obj.o vold_mnt.o medium.o partition.o \
hsfs_partition.o pcfs_partition.o fdisk_partition.o \
solaris_partition.o udfs_partition.o ufs_partition.o \
blank_partition.o vtoc.o name_factory.o vold_sysevent.o
@@ -68,7 +67,7 @@ SOFILES= ${LABS} ${DEVS} ${DBS}
CFLAGS += $(CCVERBOSE) -D_FILE_OFFSET_BITS=64
-$(PROG) := LDLIBS += -lnsl -ladm -lsmedia -lrpcsvc -lsysevent -lnvpair
+$(PROG) := LDLIBS += -lmd -lnsl -ladm -lsmedia -lrpcsvc -lsysevent -lnvpair
$(SOFILES) := LDLIBS += -lc
# to get the correct DSO flags used for compilation/linking
diff --git a/usr/src/cmd/xntpd/Makefile.cmd b/usr/src/cmd/xntpd/Makefile.cmd
index bc63142fa3..1066b30dca 100644
--- a/usr/src/cmd/xntpd/Makefile.cmd
+++ b/usr/src/cmd/xntpd/Makefile.cmd
@@ -1,11 +1,11 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-LIBS = -lsocket -lnsl -lrt -lmd5
+LIBS = -lsocket -lnsl -lrt -lmd
LIBNTP_A= libntp/libntp.a
LIBPARSE_A= libparse/libparse.a
diff --git a/usr/src/cmd/volmgt/vold/vold_md4.c b/usr/src/common/crypto/md4/md4.c
index 8247ba2970..a993886092 100644
--- a/usr/src/cmd/volmgt/vold/vold_md4.c
+++ b/usr/src/common/crypto/md4/md4.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,7 +31,7 @@
* documentation and/or software.
*/
-#include <string.h>
+#include <strings.h>
#include <sys/types.h>
#include "md4.h"
@@ -52,9 +52,9 @@
#define S33 11
#define S34 15
-static void MD4Transform(u_long [4], unsigned char [64]);
-static void Encode(unsigned char *, u_long *, unsigned int);
-static void Decode(u_long *, unsigned char *, unsigned int);
+static void MD4Transform(ulong_t [4], unsigned char [64]);
+static void Encode(unsigned char *, ulong_t *, unsigned int);
+static void Decode(ulong_t *, unsigned char *, unsigned int);
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -82,11 +82,11 @@ static unsigned char PADDING[64] = {
(a) = ROTATE_LEFT((a), (s)); \
}
#define GG(a, b, c, d, x, s) { \
- (a) += G((b), (c), (d)) + (x) + (u_long)0x5a827999; \
+ (a) += G((b), (c), (d)) + (x) + (ulong_t)0x5a827999; \
(a) = ROTATE_LEFT((a), (s)); \
}
#define HH(a, b, c, d, x, s) { \
- (a) += H((b), (c), (d)) + (x) + (u_long)0x6ed9eba1; \
+ (a) += H((b), (c), (d)) + (x) + (ulong_t)0x6ed9eba1; \
(a) = ROTATE_LEFT((a), (s)); \
}
@@ -115,20 +115,18 @@ MD4Init(context)
* context.
*/
void
-MD4Update(context, input, inputLen)
- MD4_CTX *context; /* context */
- unsigned char *input; /* input block */
- unsigned int inputLen; /* length of input block */
+MD4Update(MD4_CTX *context, const void *_RESTRICT_KYWD inptr, size_t inputLen)
{
unsigned int i, index, partLen;
+ uchar_t *input = (uchar_t *)inptr;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
- if ((context->count[0] += ((u_long)inputLen << 3))
- < ((u_long)inputLen << 3))
+ if ((context->count[0] += ((ulong_t)inputLen << 3))
+ < ((ulong_t)inputLen << 3))
context->count[1]++;
- context->count[1] += ((u_long)inputLen >> 29);
+ context->count[1] += ((ulong_t)inputLen >> 29);
partLen = 64 - index;
@@ -136,12 +134,11 @@ MD4Update(context, input, inputLen)
* Transform as many times as possible.
*/
if (inputLen >= partLen) {
- (void) memcpy((char *)&context->buffer[index],
- (char *)input, partLen);
- MD4Transform(context->state, context->buffer);
+ bcopy(input, &context->buffer[index], partLen);
+ MD4Transform(context->state, (uchar_t *)context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64) {
- MD4Transform(context->state, &input[i]);
+ MD4Transform(context->state, (uchar_t *)&input[i]);
}
index = 0;
@@ -150,8 +147,7 @@ MD4Update(context, input, inputLen)
}
/* Buffer remaining input */
- (void) memcpy((char *)&context->buffer[index],
- (char *)&input[i], inputLen-i);
+ bcopy(&input[i], &context->buffer[index], inputLen - i);
}
/*
@@ -159,9 +155,7 @@ MD4Update(context, input, inputLen)
* the message digest and zeroizing the context.
*/
void
-MD4Final(digest, context)
- unsigned char digest[16]; /* message digest */
- MD4_CTX *context; /* context */
+MD4Final(void *digest, MD4_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
@@ -181,19 +175,17 @@ MD4Final(digest, context)
/* Store state in digest */
Encode(digest, context->state, 16);
- /*
- * Zeroize sensitive information.
- */
- (void) memset((char *)context, 0, sizeof (*context));
+ /* zeroize sensitive information */
+ bzero(context, sizeof (*context));
}
/*
* MD4 basic transformation. Transforms state based on block.
*/
static void
-MD4Transform(u_long state[4], unsigned char block[64])
+MD4Transform(ulong_t state[4], unsigned char block[64])
{
- u_long a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+ ulong_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode(x, block, 64);
@@ -258,20 +250,18 @@ MD4Transform(u_long state[4], unsigned char block[64])
state[2] += c;
state[3] += d;
- /*
- * Zeroize sensitive information.
- */
- (void) memset((char *)x, 0, sizeof (x));
+ /* zeroize sensitive information */
+ bzero(x, sizeof (*x));
}
/*
- * Encodes input (u_long) into output (unsigned char). Assumes len is
+ * Encodes input (ulong_t) into output (unsigned char). Assumes len is
* a multiple of 4.
*/
static void
Encode(output, input, len)
unsigned char *output;
- u_long *input;
+ ulong_t *input;
unsigned int len;
{
unsigned int i, j;
@@ -285,20 +275,20 @@ Encode(output, input, len)
}
/*
- * Decodes input (unsigned char) into output (u_long). Assumes len is
+ * Decodes input (unsigned char) into output (ulong_t). Assumes len is
* a multiple of 4.
*/
static void
Decode(output, input, len)
- u_long *output;
+ ulong_t *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((u_long)input[j]) |
- (((u_long)input[j+1]) << 8) |
- (((u_long)input[j+2]) << 16) |
- (((u_long)input[j+3]) << 24);
+ output[i] = ((ulong_t)input[j]) |
+ (((ulong_t)input[j+1]) << 8) |
+ (((ulong_t)input[j+2]) << 16) |
+ (((ulong_t)input[j+3]) << 24);
}
diff --git a/usr/src/common/crypto/md5/md5.c b/usr/src/common/crypto/md5/md5.c
index 319254f01b..587c9961eb 100644
--- a/usr/src/common/crypto/md5/md5.c
+++ b/usr/src/common/crypto/md5/md5.c
@@ -7,10 +7,6 @@
* Cleaned-up and optimized version of MD5, based on the reference
* implementation provided in RFC 1321. See RSA Copyright information
* below.
- *
- * NOTE: All compiler data was gathered with SC4.2, and verified with SC5.x,
- * as used to build Solaris 2.7. Hopefully the compiler behavior won't
- * change for the worse in subsequent Solaris builds.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -50,267 +46,11 @@
#include <strings.h>
#endif /* !_KERNEL || _BOOT */
-#if defined(_KERNEL) && !defined(_BOOT)
-
-/*
- * In kernel module, the md5 module is created with two modlinkages:
- * - a modlmisc that allows consumers to directly call the entry points
- * MD5Init, MD5Update, and MD5Final.
- * - a modlcrypto that allows the module to register with the Kernel
- * Cryptographic Framework (KCF) as a software provider for the MD5
- * mechanisms.
- */
-
+#ifdef _KERNEL
#include <sys/systm.h>
-#include <sys/modctl.h>
-#include <sys/cmn_err.h>
-#include <sys/ddi.h>
-#include <sys/crypto/common.h>
-#include <sys/crypto/spi.h>
-#include <sys/sysmacros.h>
-#include <sys/strsun.h>
-#include <sys/note.h>
-
-extern struct mod_ops mod_miscops;
-extern struct mod_ops mod_cryptoops;
-
-/*
- * Module linkage information for the kernel.
- */
-
-static struct modlmisc modlmisc = {
- &mod_miscops,
- "MD5 Message-Digest Algorithm"
-};
-
-static struct modlcrypto modlcrypto = {
- &mod_cryptoops,
- "MD5 Kernel SW Provider 1.23"
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- (void *)&modlmisc,
- (void *)&modlcrypto,
- NULL
-};
-
-/*
- * CSPI information (entry points, provider info, etc.)
- */
-
-typedef enum md5_mech_type {
- MD5_MECH_INFO_TYPE, /* SUN_CKM_MD5 */
- MD5_HMAC_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC */
- MD5_HMAC_GEN_MECH_INFO_TYPE /* SUN_CKM_MD5_HMAC_GENERAL */
-} md5_mech_type_t;
-
-#define MD5_DIGEST_LENGTH 16 /* MD5 digest length in bytes */
-#define MD5_HMAC_BLOCK_SIZE 64 /* MD5 block size */
-#define MD5_HMAC_MIN_KEY_LEN 8 /* MD5-HMAC min key length in bits */
-#define MD5_HMAC_MAX_KEY_LEN INT_MAX /* MD5-HMAC max key length in bits */
-#define MD5_HMAC_INTS_PER_BLOCK (MD5_HMAC_BLOCK_SIZE/sizeof (uint32_t))
-
-/*
- * Context for MD5 mechanism.
- */
-typedef struct md5_ctx {
- md5_mech_type_t mc_mech_type; /* type of context */
- MD5_CTX mc_md5_ctx; /* MD5 context */
-} md5_ctx_t;
-
-/*
- * Context for MD5-HMAC and MD5-HMAC-GENERAL mechanisms.
- */
-typedef struct md5_hmac_ctx {
- md5_mech_type_t hc_mech_type; /* type of context */
- uint32_t hc_digest_len; /* digest len in bytes */
- MD5_CTX hc_icontext; /* inner MD5 context */
- MD5_CTX hc_ocontext; /* outer MD5 context */
-} md5_hmac_ctx_t;
-
-/*
- * Macros to access the MD5 or MD5-HMAC contexts from a context passed
- * by KCF to one of the entry points.
- */
-
-#define PROV_MD5_CTX(ctx) ((md5_ctx_t *)(ctx)->cc_provider_private)
-#define PROV_MD5_HMAC_CTX(ctx) ((md5_hmac_ctx_t *)(ctx)->cc_provider_private)
-/* to extract the digest length passed as mechanism parameter */
-
-#define PROV_MD5_GET_DIGEST_LEN(m, len) { \
- if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \
- (len) = (uint32_t)*((ulong_t *)mechanism->cm_param); \
- else { \
- ulong_t tmp_ulong; \
- bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \
- (len) = (uint32_t)tmp_ulong; \
- } \
-}
-
-#define PROV_MD5_DIGEST_KEY(ctx, key, len, digest) { \
- MD5Init(ctx); \
- MD5Update(ctx, key, len); \
- MD5Final(digest, ctx); \
-}
-
-/*
- * Mechanism info structure passed to KCF during registration.
- */
-static crypto_mech_info_t md5_mech_info_tab[] = {
- /* MD5 */
- {SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
- CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
- 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* MD5-HMAC */
- {SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* MD5-HMAC GENERAL */
- {SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS}
-};
-
-static void md5_provider_status(crypto_provider_handle_t, uint_t *);
-
-static crypto_control_ops_t md5_control_ops = {
- md5_provider_status
-};
+#endif /* _KERNEL */
-static int md5_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
- crypto_req_handle_t);
-static int md5_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int md5_digest_update(crypto_ctx_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int md5_digest_final(crypto_ctx_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int md5_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
- crypto_req_handle_t);
-
-static crypto_digest_ops_t md5_digest_ops = {
- md5_digest_init,
- md5_digest,
- md5_digest_update,
- NULL,
- md5_digest_final,
- md5_digest_atomic
-};
-
-static int md5_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int md5_mac_update(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
-static int md5_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
-static int md5_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int md5_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-
-static crypto_mac_ops_t md5_mac_ops = {
- md5_mac_init,
- NULL,
- md5_mac_update,
- md5_mac_final,
- md5_mac_atomic,
- md5_mac_verify_atomic
-};
-
-static int md5_create_ctx_template(crypto_provider_handle_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
- size_t *, crypto_req_handle_t);
-static int md5_free_context(crypto_ctx_t *);
-
-static crypto_ctx_ops_t md5_ctx_ops = {
- md5_create_ctx_template,
- md5_free_context
-};
-
-static crypto_ops_t md5_crypto_ops = {
- &md5_control_ops,
- &md5_digest_ops,
- NULL,
- &md5_mac_ops,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- &md5_ctx_ops
-};
-
-static crypto_provider_info_t md5_prov_info = {
- CRYPTO_SPI_VERSION_1,
- "MD5 Software Provider",
- CRYPTO_SW_PROVIDER,
- {&modlinkage},
- NULL,
- &md5_crypto_ops,
- sizeof (md5_mech_info_tab)/sizeof (crypto_mech_info_t),
- md5_mech_info_tab
-};
-
-static crypto_kcf_provider_handle_t md5_prov_handle = NULL;
-
-int
-_init(void)
-{
- int ret;
-
- if ((ret = mod_install(&modlinkage)) != 0)
- return (ret);
-
- /*
- * Register with KCF. If the registration fails, log an
- * error but do not uninstall the module, since the functionality
- * provided by misc/md5 should still be available.
- */
- if ((ret = crypto_register_provider(&md5_prov_info,
- &md5_prov_handle)) != CRYPTO_SUCCESS)
- cmn_err(CE_WARN, "md5 _init: "
- "crypto_register_provider() failed (0x%x)", ret);
-
- return (0);
-}
-
-int
-_fini(void)
-{
- int ret;
-
- /*
- * Unregister from KCF if previous registration succeeded.
- */
- if (md5_prov_handle != NULL) {
- if ((ret = crypto_unregister_provider(md5_prov_handle)) !=
- CRYPTO_SUCCESS) {
- cmn_err(CE_WARN, "md5 _fini: "
- "crypto_unregister_provider() failed (0x%x)", ret);
- return (EBUSY);
- }
- md5_prov_handle = NULL;
- }
-
- return (mod_remove(&modlinkage));
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-#endif /* _KERNEL && !_BOOT */
-
-static void Encode(uint8_t *, uint32_t *, size_t);
+static void Encode(uint8_t *, const uint32_t *, size_t);
static void MD5Transform(uint32_t, uint32_t, uint32_t, uint32_t, MD5_CTX *,
const uint8_t [64]);
@@ -662,6 +402,7 @@ MD5Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d,
#ifdef sun4v
unsigned long long *md5_consts64;
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
md5_consts64 = (unsigned long long *) md5_consts;
#endif /* sun4v */
@@ -738,38 +479,70 @@ MD5Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d,
{
#ifdef sun4v
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_15 = LOAD_LITTLE_32_f(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_14 = LOAD_LITTLE_32_e(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_13 = LOAD_LITTLE_32_d(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_12 = LOAD_LITTLE_32_c(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_11 = LOAD_LITTLE_32_b(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_10 = LOAD_LITTLE_32_a(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_9 = LOAD_LITTLE_32_9(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_8 = LOAD_LITTLE_32_8(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_7 = LOAD_LITTLE_32_7(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_6 = LOAD_LITTLE_32_6(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_5 = LOAD_LITTLE_32_5(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_4 = LOAD_LITTLE_32_4(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_3 = LOAD_LITTLE_32_3(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_2 = LOAD_LITTLE_32_2(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_1 = LOAD_LITTLE_32_1(block);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_0 = LOAD_LITTLE_32_0(block);
#else
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_15 = LOAD_LITTLE_32(block + 60);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_14 = LOAD_LITTLE_32(block + 56);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_13 = LOAD_LITTLE_32(block + 52);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_12 = LOAD_LITTLE_32(block + 48);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_11 = LOAD_LITTLE_32(block + 44);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_10 = LOAD_LITTLE_32(block + 40);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_9 = LOAD_LITTLE_32(block + 36);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_8 = LOAD_LITTLE_32(block + 32);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_7 = LOAD_LITTLE_32(block + 28);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_6 = LOAD_LITTLE_32(block + 24);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_5 = LOAD_LITTLE_32(block + 20);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_4 = LOAD_LITTLE_32(block + 16);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_3 = LOAD_LITTLE_32(block + 12);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_2 = LOAD_LITTLE_32(block + 8);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_1 = LOAD_LITTLE_32(block + 4);
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
x_0 = LOAD_LITTLE_32(block + 0);
#endif /* sun4v */
}
@@ -861,21 +634,6 @@ MD5Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d,
}
/*
- * devpro compiler optimization:
- *
- * the compiler can generate better code if it knows that `input' and
- * `output' do not point to the same source. there is no portable
- * way to tell the compiler this, but the devpro compiler recognizes the
- * `_Restrict' keyword to indicate this condition. use it if possible.
- */
-
-#if defined(__RESTRICT) && !defined(__GNUC__)
-#define restrict _Restrict
-#else
-#define restrict /* nothing */
-#endif
-
-/*
* Encode()
*
* purpose: to convert a list of numbers from big endian to little endian
@@ -886,7 +644,8 @@ MD5Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d,
*/
static void
-Encode(uint8_t *restrict output, uint32_t *restrict input, size_t input_len)
+Encode(uint8_t *_RESTRICT_KYWD output, const uint32_t *_RESTRICT_KYWD input,
+ size_t input_len)
{
size_t i, j;
@@ -899,6 +658,7 @@ Encode(uint8_t *restrict output, uint32_t *restrict input, size_t input_len)
bcopy(input + i, output + j, 4);
else *(uint32_t *)(output + j) = input[i];
#else
+ /*LINTED E_BAD_PTR_CAST_ALIGN*/
*(uint32_t *)(output + j) = input[i];
#endif /* _MD5_CHECK_ALIGNMENT */
@@ -911,1222 +671,3 @@ Encode(uint8_t *restrict output, uint32_t *restrict input, size_t input_len)
#endif
}
}
-
-#if defined(_KERNEL) && !defined(_BOOT)
-
-/*
- * KCF software provider control entry points.
- */
-/* ARGSUSED */
-static void
-md5_provider_status(crypto_provider_handle_t provider, uint_t *status)
-{
- *status = CRYPTO_PROVIDER_READY;
-}
-
-/*
- * KCF software provider digest entry points.
- */
-
-static int
-md5_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
- crypto_req_handle_t req)
-{
- if (mechanism->cm_type != MD5_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /*
- * Allocate and initialize MD5 context.
- */
- ctx->cc_provider_private = kmem_alloc(sizeof (md5_ctx_t),
- crypto_kmflag(req));
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- PROV_MD5_CTX(ctx)->mc_mech_type = MD5_MECH_INFO_TYPE;
- MD5Init(&PROV_MD5_CTX(ctx)->mc_md5_ctx);
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper MD5 digest update function for uio data.
- */
-static int
-md5_digest_update_uio(MD5_CTX *md5_ctx, crypto_data_t *data)
-{
- off_t offset = data->cd_offset;
- size_t length = data->cd_length;
- uint_t vec_idx;
- size_t cur_len;
-
- /* we support only kernel buffer */
- if (data->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Jump to the first iovec containing data to be
- * digested.
- */
- for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt &&
- offset >= data->cd_uio->uio_iov[vec_idx].iov_len;
- offset -= data->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == data->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- /*
- * Now do the digesting on the iovecs.
- */
- while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) {
- cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
-
- MD5Update(md5_ctx, data->cd_uio->uio_iov[vec_idx].iov_base +
- offset, cur_len);
-
- length -= cur_len;
- vec_idx++;
- offset = 0;
- }
-
- if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) {
- /*
- * The end of the specified iovec's was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper MD5 digest final function for uio data.
- * digest_len is the length of the desired digest. If digest_len
- * is smaller than the default MD5 digest length, the caller
- * must pass a scratch buffer, digest_scratch, which must
- * be at least MD5_DIGEST_LENGTH bytes.
- */
-static int
-md5_digest_final_uio(MD5_CTX *md5_ctx, crypto_data_t *digest,
- ulong_t digest_len, uchar_t *digest_scratch)
-{
- off_t offset = digest->cd_offset;
- uint_t vec_idx;
-
- /* we support only kernel buffer */
- if (digest->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Jump to the first iovec containing ptr to the digest to
- * be returned.
- */
- for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len &&
- vec_idx < digest->cd_uio->uio_iovcnt;
- offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == digest->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is
- * larger than the total size of the buffers
- * it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- if (offset + digest_len <=
- digest->cd_uio->uio_iov[vec_idx].iov_len) {
- /*
- * The computed MD5 digest will fit in the current
- * iovec.
- */
- if (digest_len != MD5_DIGEST_LENGTH) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- MD5Final(digest_scratch, md5_ctx);
- bcopy(digest_scratch, (uchar_t *)digest->
- cd_uio->uio_iov[vec_idx].iov_base + offset,
- digest_len);
- } else {
- MD5Final((uchar_t *)digest->
- cd_uio->uio_iov[vec_idx].iov_base + offset,
- md5_ctx);
- }
- } else {
- /*
- * The computed digest will be crossing one or more iovec's.
- * This is bad performance-wise but we need to support it.
- * Allocate a small scratch buffer on the stack and
- * copy it piece meal to the specified digest iovec's.
- */
- uchar_t digest_tmp[MD5_DIGEST_LENGTH];
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- MD5Final(digest_tmp, md5_ctx);
-
- while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) {
- cur_len = MIN(digest->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
- bcopy(digest_tmp + scratch_offset,
- digest->cd_uio->uio_iov[vec_idx].iov_base + offset,
- cur_len);
-
- length -= cur_len;
- vec_idx++;
- scratch_offset += cur_len;
- offset = 0;
- }
-
- if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) {
- /*
- * The end of the specified iovec's was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it
- * provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper MD5 digest update for mblk's.
- */
-static int
-md5_digest_update_mblk(MD5_CTX *md5_ctx, crypto_data_t *data)
-{
- off_t offset = data->cd_offset;
- size_t length = data->cd_length;
- mblk_t *mp;
- size_t cur_len;
-
- /*
- * Jump to the first mblk_t containing data to be digested.
- */
- for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- /*
- * Now do the digesting on the mblk chain.
- */
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- MD5Update(md5_ctx, mp->b_rptr + offset, cur_len);
- length -= cur_len;
- offset = 0;
- mp = mp->b_cont;
- }
-
- if (mp == NULL && length > 0) {
- /*
- * The end of the mblk was reached but the length requested
- * could not be processed, i.e. The caller requested
- * to digest more data than it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper MD5 digest final for mblk's.
- * digest_len is the length of the desired digest. If digest_len
- * is smaller than the default MD5 digest length, the caller
- * must pass a scratch buffer, digest_scratch, which must
- * be at least MD5_DIGEST_LENGTH bytes.
- */
-static int
-md5_digest_final_mblk(MD5_CTX *md5_ctx, crypto_data_t *digest,
- ulong_t digest_len, uchar_t *digest_scratch)
-{
- off_t offset = digest->cd_offset;
- mblk_t *mp;
-
- /*
- * Jump to the first mblk_t that will be used to store the digest.
- */
- for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- if (offset + digest_len <= MBLKL(mp)) {
- /*
- * The computed MD5 digest will fit in the current mblk.
- * Do the MD5Final() in-place.
- */
- if (digest_len != MD5_DIGEST_LENGTH) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- MD5Final(digest_scratch, md5_ctx);
- bcopy(digest_scratch, mp->b_rptr + offset, digest_len);
- } else {
- MD5Final(mp->b_rptr + offset, md5_ctx);
- }
- } else {
- /*
- * The computed digest will be crossing one or more mblk's.
- * This is bad performance-wise but we need to support it.
- * Allocate a small scratch buffer on the stack and
- * copy it piece meal to the specified digest iovec's.
- */
- uchar_t digest_tmp[MD5_DIGEST_LENGTH];
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- MD5Final(digest_tmp, md5_ctx);
-
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- bcopy(digest_tmp + scratch_offset,
- mp->b_rptr + offset, cur_len);
-
- length -= cur_len;
- mp = mp->b_cont;
- scratch_offset += cur_len;
- offset = 0;
- }
-
- if (mp == NULL && length > 0) {
- /*
- * The end of the specified mblk was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it
- * provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/* ARGSUSED */
-static int
-md5_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((digest->cd_length == 0) ||
- (digest->cd_length < MD5_DIGEST_LENGTH)) {
- digest->cd_length = MD5_DIGEST_LENGTH;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do the MD5 update on the specified input data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- MD5Update(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_update_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_update_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret != CRYPTO_SUCCESS) {
- /* the update failed, free context and bail */
- kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
- ctx->cc_provider_private = NULL;
- digest->cd_length = 0;
- return (ret);
- }
-
- /*
- * Do an MD5 final, must be done separately since the digest
- * type can be different than the input data type.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- MD5Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &PROV_MD5_CTX(ctx)->mc_md5_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_final_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- digest, MD5_DIGEST_LENGTH, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_final_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- digest, MD5_DIGEST_LENGTH, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- /* all done, free context and return */
-
- if (ret == CRYPTO_SUCCESS) {
- digest->cd_length = MD5_DIGEST_LENGTH;
- } else {
- digest->cd_length = 0;
- }
-
- kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
- ctx->cc_provider_private = NULL;
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-md5_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * Do the MD5 update on the specified input data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- MD5Update(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_update_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_update_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-md5_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((digest->cd_length == 0) ||
- (digest->cd_length < MD5_DIGEST_LENGTH)) {
- digest->cd_length = MD5_DIGEST_LENGTH;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do an MD5 final.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- MD5Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &PROV_MD5_CTX(ctx)->mc_md5_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_final_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- digest, MD5_DIGEST_LENGTH, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_final_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
- digest, MD5_DIGEST_LENGTH, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- /* all done, free context and return */
-
- if (ret == CRYPTO_SUCCESS) {
- digest->cd_length = MD5_DIGEST_LENGTH;
- } else {
- digest->cd_length = 0;
- }
-
- kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
- ctx->cc_provider_private = NULL;
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-md5_digest_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_data_t *data, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- MD5_CTX md5_ctx;
-
- if (mechanism->cm_type != MD5_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /*
- * Do the MD5 init.
- */
- MD5Init(&md5_ctx);
-
- /*
- * Do the MD5 update on the specified input data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- MD5Update(&md5_ctx, data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_update_uio(&md5_ctx, data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_update_mblk(&md5_ctx, data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret != CRYPTO_SUCCESS) {
- /* the update failed, bail */
- digest->cd_length = 0;
- return (ret);
- }
-
- /*
- * Do an MD5 final, must be done separately since the digest
- * type can be different than the input data type.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- MD5Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &md5_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_final_uio(&md5_ctx, digest,
- MD5_DIGEST_LENGTH, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_final_mblk(&md5_ctx, digest,
- MD5_DIGEST_LENGTH, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS) {
- digest->cd_length = MD5_DIGEST_LENGTH;
- } else {
- digest->cd_length = 0;
- }
-
- return (ret);
-}
-
-/*
- * KCF software provider mac entry points.
- *
- * MD5 HMAC is: MD5(key XOR opad, MD5(key XOR ipad, text))
- *
- * Init:
- * The initialization routine initializes what we denote
- * as the inner and outer contexts by doing
- * - for inner context: MD5(key XOR ipad)
- * - for outer context: MD5(key XOR opad)
- *
- * Update:
- * Each subsequent MD5 HMAC update will result in an
- * update of the inner context with the specified data.
- *
- * Final:
- * The MD5 HMAC final will do a MD5 final operation on the
- * inner context, and the resulting digest will be used
- * as the data for an update on the outer context. Last
- * but not least, an MD5 final on the outer context will
- * be performed to obtain the MD5 HMAC digest to return
- * to the user.
- */
-
-/*
- * Initialize a MD5-HMAC context.
- */
-static void
-md5_mac_init_ctx(md5_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
-{
- uint32_t ipad[MD5_HMAC_INTS_PER_BLOCK];
- uint32_t opad[MD5_HMAC_INTS_PER_BLOCK];
- uint_t i;
-
- bzero(ipad, MD5_HMAC_BLOCK_SIZE);
- bzero(opad, MD5_HMAC_BLOCK_SIZE);
-
- bcopy(keyval, ipad, length_in_bytes);
- bcopy(keyval, opad, length_in_bytes);
-
- /* XOR key with ipad (0x36) and opad (0x5c) */
- for (i = 0; i < MD5_HMAC_INTS_PER_BLOCK; i++) {
- ipad[i] ^= 0x36363636;
- opad[i] ^= 0x5c5c5c5c;
- }
-
- /* perform MD5 on ipad */
- MD5Init(&ctx->hc_icontext);
- MD5Update(&ctx->hc_icontext, ipad, MD5_HMAC_BLOCK_SIZE);
-
- /* perform MD5 on opad */
- MD5Init(&ctx->hc_ocontext);
- MD5Update(&ctx->hc_ocontext, opad, MD5_HMAC_BLOCK_SIZE);
-}
-
-/*
- * Initializes a multi-part MAC operation.
- */
-static int
-md5_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
- mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- ctx->cc_provider_private = kmem_alloc(sizeof (md5_hmac_ctx_t),
- crypto_kmflag(req));
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, PROV_MD5_HMAC_CTX(ctx),
- sizeof (md5_hmac_ctx_t));
- } else {
- /* no context template, compute context */
- if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
- uchar_t digested_key[MD5_DIGEST_LENGTH];
- md5_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
-
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_MD5_DIGEST_KEY(&hmac_ctx->hc_icontext,
- key->ck_data, keylen_in_bytes, digested_key);
- md5_mac_init_ctx(PROV_MD5_HMAC_CTX(ctx),
- digested_key, MD5_DIGEST_LENGTH);
- } else {
- md5_mac_init_ctx(PROV_MD5_HMAC_CTX(ctx),
- key->ck_data, keylen_in_bytes);
- }
- }
-
- /*
- * Get the mechanism parameters, if applicable.
- */
- PROV_MD5_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
- if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t))
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- PROV_MD5_GET_DIGEST_LEN(mechanism,
- PROV_MD5_HMAC_CTX(ctx)->hc_digest_len);
- if (PROV_MD5_HMAC_CTX(ctx)->hc_digest_len >
- MD5_DIGEST_LENGTH)
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- }
-
- if (ret != CRYPTO_SUCCESS) {
- bzero(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
- kmem_free(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
- ctx->cc_provider_private = NULL;
- }
-
- return (ret);
-}
-
-
-/* ARGSUSED */
-static int
-md5_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * Do an MD5 update of the inner context using the specified
- * data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- MD5Update(&PROV_MD5_HMAC_CTX(ctx)->hc_icontext,
- data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_update_uio(
- &PROV_MD5_HMAC_CTX(ctx)->hc_icontext, data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_update_mblk(
- &PROV_MD5_HMAC_CTX(ctx)->hc_icontext, data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-md5_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[MD5_DIGEST_LENGTH];
- uint32_t digest_len = MD5_DIGEST_LENGTH;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- if (PROV_MD5_HMAC_CTX(ctx)->hc_mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE)
- digest_len = PROV_MD5_HMAC_CTX(ctx)->hc_digest_len;
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
- mac->cd_length = digest_len;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do an MD5 final on the inner context.
- */
- MD5Final(digest, &PROV_MD5_HMAC_CTX(ctx)->hc_icontext);
-
- /*
- * Do an MD5 update on the outer context, feeding the inner
- * digest as data.
- */
- MD5Update(&PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, digest,
- MD5_DIGEST_LENGTH);
-
- /*
- * Do an MD5 final on the outer context, storing the computing
- * digest in the users buffer.
- */
- switch (mac->cd_format) {
- case CRYPTO_DATA_RAW:
- if (digest_len != MD5_DIGEST_LENGTH) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- MD5Final(digest,
- &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext);
- bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len);
- } else {
- MD5Final((unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset,
- &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext);
- }
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_final_uio(
- &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, mac,
- digest_len, digest);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_final_mblk(
- &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, mac,
- digest_len, digest);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS) {
- mac->cd_length = digest_len;
- } else {
- mac->cd_length = 0;
- }
-
- bzero(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
- kmem_free(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
- ctx->cc_provider_private = NULL;
-
- return (ret);
-}
-
-#define MD5_MAC_UPDATE(data, ctx, ret) { \
- switch (data->cd_format) { \
- case CRYPTO_DATA_RAW: \
- MD5Update(&(ctx).hc_icontext, \
- data->cd_raw.iov_base + data->cd_offset, \
- data->cd_length); \
- break; \
- case CRYPTO_DATA_UIO: \
- ret = md5_digest_update_uio(&(ctx).hc_icontext, data); \
- break; \
- case CRYPTO_DATA_MBLK: \
- ret = md5_digest_update_mblk(&(ctx).hc_icontext, \
- data); \
- break; \
- default: \
- ret = CRYPTO_ARGUMENTS_BAD; \
- } \
-}
-
-
-/* ARGSUSED */
-static int
-md5_mac_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
- crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[MD5_DIGEST_LENGTH];
- md5_hmac_ctx_t md5_hmac_ctx;
- uint32_t digest_len = MD5_DIGEST_LENGTH;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
- mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, &md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
- } else {
- /* no context template, compute context */
- if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_MD5_DIGEST_KEY(&md5_hmac_ctx.hc_icontext,
- key->ck_data, keylen_in_bytes, digest);
- md5_mac_init_ctx(&md5_hmac_ctx, digest,
- MD5_DIGEST_LENGTH);
- } else {
- md5_mac_init_ctx(&md5_hmac_ctx, key->ck_data,
- keylen_in_bytes);
- }
- }
-
- /*
- * Get the mechanism parameters, if applicable.
- */
- if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t)) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- PROV_MD5_GET_DIGEST_LEN(mechanism, digest_len);
- if (digest_len > MD5_DIGEST_LENGTH) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- }
-
- /* do an MD5 update of the inner context using the specified data */
- MD5_MAC_UPDATE(data, md5_hmac_ctx, ret);
- if (ret != CRYPTO_SUCCESS)
- /* the update failed, free context and bail */
- goto bail;
-
- /* do an MD5 final on the inner context */
- MD5Final(digest, &md5_hmac_ctx.hc_icontext);
-
- /*
- * Do an MD5 update on the outer context, feeding the inner
- * digest as data.
- */
- MD5Update(&md5_hmac_ctx.hc_ocontext, digest, MD5_DIGEST_LENGTH);
-
- /*
- * Do an MD5 final on the outer context, storing the computed
- * digest in the users buffer.
- */
- switch (mac->cd_format) {
- case CRYPTO_DATA_RAW:
- if (digest_len != MD5_DIGEST_LENGTH) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- MD5Final(digest, &md5_hmac_ctx.hc_ocontext);
- bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len);
- } else {
- MD5Final((unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, &md5_hmac_ctx.hc_ocontext);
- }
- break;
- case CRYPTO_DATA_UIO:
- ret = md5_digest_final_uio(&md5_hmac_ctx.hc_ocontext, mac,
- digest_len, digest);
- break;
- case CRYPTO_DATA_MBLK:
- ret = md5_digest_final_mblk(&md5_hmac_ctx.hc_ocontext, mac,
- digest_len, digest);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS) {
- mac->cd_length = digest_len;
- } else {
- mac->cd_length = 0;
- }
- /* Extra paranoia: zeroizing the local context on the stack */
- bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
-
- return (ret);
-bail:
- bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
- mac->cd_length = 0;
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-md5_mac_verify_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
- crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[MD5_DIGEST_LENGTH];
- md5_hmac_ctx_t md5_hmac_ctx;
- uint32_t digest_len = MD5_DIGEST_LENGTH;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
- mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, &md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
- } else {
- /* no context template, compute context */
- if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_MD5_DIGEST_KEY(&md5_hmac_ctx.hc_icontext,
- key->ck_data, keylen_in_bytes, digest);
- md5_mac_init_ctx(&md5_hmac_ctx, digest,
- MD5_DIGEST_LENGTH);
- } else {
- md5_mac_init_ctx(&md5_hmac_ctx, key->ck_data,
- keylen_in_bytes);
- }
- }
-
- /*
- * Get the mechanism parameters, if applicable.
- */
- if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t)) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- PROV_MD5_GET_DIGEST_LEN(mechanism, digest_len);
- if (digest_len > MD5_DIGEST_LENGTH) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- }
-
- if (mac->cd_length != digest_len) {
- ret = CRYPTO_INVALID_MAC;
- goto bail;
- }
-
- /* do an MD5 update of the inner context using the specified data */
- MD5_MAC_UPDATE(data, md5_hmac_ctx, ret);
- if (ret != CRYPTO_SUCCESS)
- /* the update failed, free context and bail */
- goto bail;
-
- /* do an MD5 final on the inner context */
- MD5Final(digest, &md5_hmac_ctx.hc_icontext);
-
- /*
- * Do an MD5 update on the outer context, feeding the inner
- * digest as data.
- */
- MD5Update(&md5_hmac_ctx.hc_ocontext, digest, MD5_DIGEST_LENGTH);
-
- /*
- * Do an MD5 final on the outer context, storing the computed
- * digest in the local digest buffer.
- */
- MD5Final(digest, &md5_hmac_ctx.hc_ocontext);
-
- /*
- * Compare the computed digest against the expected digest passed
- * as argument.
- */
- switch (mac->cd_format) {
-
- case CRYPTO_DATA_RAW:
- if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len) != 0)
- ret = CRYPTO_INVALID_MAC;
- break;
-
- case CRYPTO_DATA_UIO: {
- off_t offset = mac->cd_offset;
- uint_t vec_idx;
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- /* we support only kernel buffer */
- if (mac->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /* jump to the first iovec containing the expected digest */
- for (vec_idx = 0;
- offset >= mac->cd_uio->uio_iov[vec_idx].iov_len &&
- vec_idx < mac->cd_uio->uio_iovcnt;
- offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == mac->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is
- * larger than the total size of the buffers
- * it provided.
- */
- ret = CRYPTO_DATA_LEN_RANGE;
- break;
- }
-
- /* do the comparison of computed digest vs specified one */
- while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) {
- cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
-
- if (bcmp(digest + scratch_offset,
- mac->cd_uio->uio_iov[vec_idx].iov_base + offset,
- cur_len) != 0) {
- ret = CRYPTO_INVALID_MAC;
- break;
- }
-
- length -= cur_len;
- vec_idx++;
- scratch_offset += cur_len;
- offset = 0;
- }
- break;
- }
-
- case CRYPTO_DATA_MBLK: {
- off_t offset = mac->cd_offset;
- mblk_t *mp;
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- /* jump to the first mblk_t containing the expected digest */
- for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than
- * the total size of the buffers it provided.
- */
- ret = CRYPTO_DATA_LEN_RANGE;
- break;
- }
-
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- if (bcmp(digest + scratch_offset,
- mp->b_rptr + offset, cur_len) != 0) {
- ret = CRYPTO_INVALID_MAC;
- break;
- }
-
- length -= cur_len;
- mp = mp->b_cont;
- scratch_offset += cur_len;
- offset = 0;
- }
- break;
- }
-
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
- return (ret);
-bail:
- bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
- mac->cd_length = 0;
- return (ret);
-}
-
-/*
- * KCF software provider context management entry points.
- */
-
-/* ARGSUSED */
-static int
-md5_create_ctx_template(crypto_provider_handle_t provider,
- crypto_mechanism_t *mechanism, crypto_key_t *key,
- crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
- crypto_req_handle_t req)
-{
- md5_hmac_ctx_t *md5_hmac_ctx_tmpl;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- if ((mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE) &&
- (mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE))
- return (CRYPTO_MECHANISM_INVALID);
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Allocate and initialize MD5 context.
- */
- md5_hmac_ctx_tmpl = kmem_alloc(sizeof (md5_hmac_ctx_t),
- crypto_kmflag(req));
- if (md5_hmac_ctx_tmpl == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
- uchar_t digested_key[MD5_DIGEST_LENGTH];
-
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_MD5_DIGEST_KEY(&md5_hmac_ctx_tmpl->hc_icontext,
- key->ck_data, keylen_in_bytes, digested_key);
- md5_mac_init_ctx(md5_hmac_ctx_tmpl, digested_key,
- MD5_DIGEST_LENGTH);
- } else {
- md5_mac_init_ctx(md5_hmac_ctx_tmpl, key->ck_data,
- keylen_in_bytes);
- }
-
- md5_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
- *ctx_template = (crypto_spi_ctx_template_t)md5_hmac_ctx_tmpl;
- *ctx_template_size = sizeof (md5_hmac_ctx_t);
-
- return (CRYPTO_SUCCESS);
-}
-
-static int
-md5_free_context(crypto_ctx_t *ctx)
-{
- uint_t ctx_len;
- md5_mech_type_t mech_type;
-
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_SUCCESS);
-
- /*
- * We have to free either MD5 or MD5-HMAC contexts, which
- * have different lengths.
- */
-
- mech_type = PROV_MD5_CTX(ctx)->mc_mech_type;
- if (mech_type == MD5_MECH_INFO_TYPE)
- ctx_len = sizeof (md5_ctx_t);
- else {
- ASSERT(mech_type == MD5_HMAC_MECH_INFO_TYPE ||
- mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE);
- ctx_len = sizeof (md5_hmac_ctx_t);
- }
-
- bzero(ctx->cc_provider_private, ctx_len);
- kmem_free(ctx->cc_provider_private, ctx_len);
- ctx->cc_provider_private = NULL;
-
- return (CRYPTO_SUCCESS);
-}
-
-#endif /* _KERNEL && !_BOOT */
diff --git a/usr/src/common/crypto/md5/md5_byteswap.h b/usr/src/common/crypto/md5/md5_byteswap.h
index 8b5df83bba..373f0cf02d 100644
--- a/usr/src/common/crypto/md5/md5_byteswap.h
+++ b/usr/src/common/crypto/md5/md5_byteswap.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -120,6 +120,24 @@ load_little_16(uint16_t *addr)
extern uint32_t load_little_32(uint32_t *);
#endif /* !__GNUC__ */
+/* Placate lint */
+#if defined(__lint)
+uint32_t
+load_little_32(uint32_t *addr)
+{
+ return (*addr);
+}
+#endif /* __lint */
+
+#else /* !sun4u */
+
+/* big endian -- will work on little endian, but slowly */
+/* Since we do byte operations, we don't have to check for alignment. */
+#define LOAD_LITTLE_32(addr) \
+ ((addr)[0] | ((addr)[1] << 8) | ((addr)[2] << 16) | ((addr)[3] << 24))
+
+#endif /* sun4u */
+
#if defined(sun4v)
/*
@@ -241,23 +259,6 @@ extern uint32_t load_little_32_f(uint32_t *);
#endif /* !__GNUC__ */
#endif /* sun4v */
-/* Placate lint */
-#if defined(__lint)
-uint32_t
-load_little_32(uint32_t *addr)
-{
- return (*addr);
-}
-#endif /* __lint */
-
-#else /* !sun4u */
-
-/* big endian -- will work on little endian, but slowly */
-/* Since we do byte operations, we don't have to check for alignment. */
-#define LOAD_LITTLE_32(addr) \
- ((addr)[0] | ((addr)[1] << 8) | ((addr)[2] << 16) | ((addr)[3] << 24))
-
-#endif /* sun4u */
#endif /* _LITTLE_ENDIAN */
#ifdef __cplusplus
diff --git a/usr/src/common/crypto/sha1/sha1.c b/usr/src/common/crypto/sha1/sha1.c
index 6406e7ea60..fdbd9bf3c8 100644
--- a/usr/src/common/crypto/sha1/sha1.c
+++ b/usr/src/common/crypto/sha1/sha1.c
@@ -41,262 +41,74 @@
#include <sys/sha1.h>
#include <sys/sha1_consts.h>
-#ifdef _KERNEL
-
-#include <sys/modctl.h>
-#include <sys/cmn_err.h>
-#include <sys/note.h>
-#include <sys/crypto/common.h>
-#include <sys/crypto/spi.h>
-#include <sys/strsun.h>
-
-/*
- * The sha1 module is created with two modlinkages:
- * - a modlmisc that allows consumers to directly call the entry points
- * SHA1Init, SHA1Update, and SHA1Final.
- * - a modlcrypto that allows the module to register with the Kernel
- * Cryptographic Framework (KCF) as a software provider for the SHA1
- * mechanisms.
- */
-
-#endif /* _KERNEL */
#ifndef _KERNEL
#include <strings.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/systeminfo.h>
-#endif /* !_KERNEL */
+#endif /* !_KERNEL */
-static void Encode(uint8_t *, uint32_t *, size_t);
-static void SHA1Transform(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t,
- SHA1_CTX *, const uint8_t *);
-
-static uint8_t PADDING[64] = { 0x80, /* all zeros */ };
+static void Encode(uint8_t *, const uint32_t *, size_t);
-/*
- * F, G, and H are the basic SHA1 functions.
- */
-#define F(b, c, d) (((b) & (c)) | ((~b) & (d)))
-#define G(b, c, d) ((b) ^ (c) ^ (d))
-#define H(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+#if defined(__sparc)
-/*
- * ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) \
- (((x) << (n)) | ((x) >> ((sizeof (x) * NBBY)-(n))))
+#define SHA1_TRANSFORM(ctx, in) \
+ SHA1Transform((ctx)->state[0], (ctx)->state[1], (ctx)->state[2], \
+ (ctx)->state[3], (ctx)->state[4], (ctx), (in))
-#ifdef _KERNEL
+static void SHA1Transform(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t,
+ SHA1_CTX *, const uint8_t *);
-static struct modlmisc modlmisc = {
- &mod_miscops,
- "SHA1 Message-Digest Algorithm"
-};
+#else
-static struct modlcrypto modlcrypto = {
- &mod_cryptoops,
- "SHA1 Kernel SW Provider %I%"
-};
+#define SHA1_TRANSFORM(ctx, in) SHA1Transform((ctx), (in))
-static struct modlinkage modlinkage = {
- MODREV_1, &modlmisc, &modlcrypto, NULL
-};
+static void SHA1Transform(SHA1_CTX *, const uint8_t *);
-/*
- * CSPI information (entry points, provider info, etc.)
- */
+#endif
-typedef enum sha1_mech_type {
- SHA1_MECH_INFO_TYPE, /* SUN_CKM_SHA1 */
- SHA1_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC */
- SHA1_HMAC_GEN_MECH_INFO_TYPE /* SUN_CKM_SHA1_HMAC_GENERAL */
-} sha1_mech_type_t;
-#define SHA1_DIGEST_LENGTH 20 /* SHA1 digest length in bytes */
-#define SHA1_HMAC_BLOCK_SIZE 64 /* SHA1-HMAC block size */
-#define SHA1_HMAC_MIN_KEY_LEN 8 /* SHA1-HMAC min key length in bits */
-#define SHA1_HMAC_MAX_KEY_LEN INT_MAX /* SHA1-HMAC max key length in bits */
-#define SHA1_HMAC_INTS_PER_BLOCK (SHA1_HMAC_BLOCK_SIZE/sizeof (uint32_t))
+static uint8_t PADDING[64] = { 0x80, /* all zeros */ };
/*
- * Context for SHA1 mechanism.
+ * F, G, and H are the basic SHA1 functions.
*/
-typedef struct sha1_ctx {
- sha1_mech_type_t sc_mech_type; /* type of context */
- SHA1_CTX sc_sha1_ctx; /* SHA1 context */
-} sha1_ctx_t;
+#define F(b, c, d) (((b) & (c)) | ((~b) & (d)))
+#define G(b, c, d) ((b) ^ (c) ^ (d))
+#define H(b, c, d) (((b) & (c)) | (((b)|(c)) & (d)))
/*
- * Context for SHA1-HMAC and SHA1-HMAC-GENERAL mechanisms.
+ * ROTATE_LEFT rotates x left n bits.
*/
-typedef struct sha1_hmac_ctx {
- sha1_mech_type_t hc_mech_type; /* type of context */
- uint32_t hc_digest_len; /* digest len in bytes */
- SHA1_CTX hc_icontext; /* inner SHA1 context */
- SHA1_CTX hc_ocontext; /* outer SHA1 context */
-} sha1_hmac_ctx_t;
-/*
- * Macros to access the SHA1 or SHA1-HMAC contexts from a context passed
- * by KCF to one of the entry points.
- */
+#if defined(__GNUC__) && defined(_LP64)
+static __inline__ uint64_t
+ROTATE_LEFT(uint64_t value, uint32_t n)
+{
+ uint32_t t32;
-#define PROV_SHA1_CTX(ctx) ((sha1_ctx_t *)(ctx)->cc_provider_private)
-#define PROV_SHA1_HMAC_CTX(ctx) ((sha1_hmac_ctx_t *)(ctx)->cc_provider_private)
-
-/* to extract the digest length passed as mechanism parameter */
-#define PROV_SHA1_GET_DIGEST_LEN(m, len) { \
- if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \
- (len) = (uint32_t)*((ulong_t *)mechanism->cm_param); \
- else { \
- ulong_t tmp_ulong; \
- bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \
- (len) = (uint32_t)tmp_ulong; \
- } \
+ t32 = (uint32_t)value;
+ return ((t32 << n) | (t32 >> (32 - n)));
}
-#define PROV_SHA1_DIGEST_KEY(ctx, key, len, digest) { \
- SHA1Init(ctx); \
- SHA1Update(ctx, key, len); \
- SHA1Final(digest, ctx); \
-}
+#else
-/*
- * Mechanism info structure passed to KCF during registration.
- */
-static crypto_mech_info_t sha1_mech_info_tab[] = {
- /* SHA1 */
- {SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE,
- CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
- 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA1-HMAC */
- {SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA1-HMAC GENERAL */
- {SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS}
-};
-
-static void sha1_provider_status(crypto_provider_handle_t, uint_t *);
-
-static crypto_control_ops_t sha1_control_ops = {
- sha1_provider_status
-};
-
-static int sha1_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
- crypto_req_handle_t);
-static int sha1_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int sha1_digest_update(crypto_ctx_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int sha1_digest_final(crypto_ctx_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int sha1_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
- crypto_req_handle_t);
-
-static crypto_digest_ops_t sha1_digest_ops = {
- sha1_digest_init,
- sha1_digest,
- sha1_digest_update,
- NULL,
- sha1_digest_final,
- sha1_digest_atomic
-};
-
-static int sha1_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int sha1_mac_update(crypto_ctx_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int sha1_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
-static int sha1_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int sha1_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-
-static crypto_mac_ops_t sha1_mac_ops = {
- sha1_mac_init,
- NULL,
- sha1_mac_update,
- sha1_mac_final,
- sha1_mac_atomic,
- sha1_mac_verify_atomic
-};
-
-static int sha1_create_ctx_template(crypto_provider_handle_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
- size_t *, crypto_req_handle_t);
-static int sha1_free_context(crypto_ctx_t *);
-
-static crypto_ctx_ops_t sha1_ctx_ops = {
- sha1_create_ctx_template,
- sha1_free_context
-};
-
-static crypto_ops_t sha1_crypto_ops = {
- &sha1_control_ops,
- &sha1_digest_ops,
- NULL,
- &sha1_mac_ops,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- &sha1_ctx_ops
-};
-
-static crypto_provider_info_t sha1_prov_info = {
- CRYPTO_SPI_VERSION_1,
- "SHA1 Software Provider",
- CRYPTO_SW_PROVIDER,
- {&modlinkage},
- NULL,
- &sha1_crypto_ops,
- sizeof (sha1_mech_info_tab)/sizeof (crypto_mech_info_t),
- sha1_mech_info_tab
-};
-
-static crypto_kcf_provider_handle_t sha1_prov_handle = NULL;
-
-int
-_init()
-{
- int ret;
+#define ROTATE_LEFT(x, n) \
+ (((x) << (n)) | ((x) >> ((sizeof (x) * NBBY)-(n))))
- if ((ret = mod_install(&modlinkage)) != 0)
- return (ret);
+#endif
- /*
- * Register with KCF. If the registration fails, log an
- * error but do not uninstall the module, since the functionality
- * provided by misc/sha1 should still be available.
- */
- if ((ret = crypto_register_provider(&sha1_prov_info,
- &sha1_prov_handle)) != CRYPTO_SUCCESS)
- cmn_err(CE_WARN, "sha1 _init: "
- "crypto_register_provider() failed (0x%x)", ret);
+#if defined(__GNUC__) && (defined(__i386) || defined(__amd64))
- return (0);
-}
+#define HAVE_BSWAP
-int
-_info(struct modinfo *modinfop)
+extern __inline__ uint32_t bswap(uint32_t value)
{
- return (mod_info(&modlinkage, modinfop));
+ __asm__("bswap %0" : "+r" (value));
+ return (value);
}
-#endif /* _KERNEL */
+#endif
/*
* SHA1Init()
@@ -324,8 +136,6 @@ SHA1Init(SHA1_CTX *ctx)
}
#ifdef VIS_SHA1
-
-
#ifdef _KERNEL
#include <sys/regset.h>
@@ -340,69 +150,6 @@ extern void sha1_restorefp(kfpu_t *);
uint32_t vis_sha1_svfp_threshold = 128;
-#else /* !_KERNEL */
-
-static boolean_t checked_vis = B_FALSE;
-static int usevis = 0;
-
-static int
-havevis()
-{
- char *buf = NULL;
- char *isa_token;
- char *lasts;
- int ret = 0;
- size_t bufsize = 255; /* UltraSPARC III needs 115 chars */
- int v9_isa_token, vis_isa_token, isa_token_num;
-
- if (checked_vis) {
- return (usevis);
- }
-
- if ((buf = malloc(bufsize)) == NULL) {
- return (0);
- }
-
- if ((ret = sysinfo(SI_ISALIST, buf, bufsize)) == -1) {
- free(buf);
- return (0);
- } else if (ret > bufsize) {
- /* We lost some because our buffer was too small */
- if ((buf = realloc(buf, bufsize = ret)) == NULL) {
- return (0);
- }
- if ((ret = sysinfo(SI_ISALIST, buf, bufsize)) == -1) {
- free(buf);
- return (0);
- }
- }
-
- /*
- * Check the relative posistions of sparcv9 & sparcv9+vis
- * because they are listed in (best) performance order.
- * For example: The Niagara chip reports it has VIS but the
- * SHA1 code runs faster without this optimisation.
- */
- isa_token = strtok_r(buf, " ", &lasts);
- v9_isa_token = vis_isa_token = -1;
- isa_token_num = 0;
- do {
- if (strcmp(isa_token, "sparcv9") == 0) {
- v9_isa_token = isa_token_num;
- } else if (strcmp(isa_token, "sparcv9+vis") == 0) {
- vis_isa_token = isa_token_num;
- }
- isa_token_num++;
- } while (isa_token = strtok_r(NULL, " ", &lasts));
-
- if (vis_isa_token != -1 && vis_isa_token < v9_isa_token)
- usevis = 1;
- free(buf);
-
- checked_vis = B_TRUE;
- return (usevis);
-}
-
#endif /* _KERNEL */
/*
@@ -415,7 +162,7 @@ static uint64_t VIS[] = {
0x8f1bbcdcca62c1d6ULL,
0x012389ab456789abULL};
-extern void SHA1TransformVIS(uint64_t *, uint64_t *, uint32_t *, uint64_t *);
+extern void SHA1TransformVIS(uint64_t *, uint32_t *, uint32_t *, uint64_t *);
/*
@@ -424,18 +171,21 @@ extern void SHA1TransformVIS(uint64_t *, uint64_t *, uint32_t *, uint64_t *);
* purpose: continues an sha1 digest operation, using the message block
* to update the context.
* input: SHA1_CTX * : the context to update
- * uint8_t * : the message block
- * uint32_t : the length of the message block in bytes
+ * void * : the message block
+ * size_t : the length of the message block in bytes
* output: void
*/
void
-SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
+SHA1Update(SHA1_CTX *ctx, const void *inptr, size_t input_len)
{
uint32_t i, buf_index, buf_len;
uint64_t X0[40], input64[8];
+ const uint8_t *input = inptr;
#ifdef _KERNEL
int usevis = 0;
+#else
+ int usevis = 1;
#endif /* _KERNEL */
/* check for noop */
@@ -457,18 +207,18 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
i = 0;
if (input_len >= buf_len) {
#ifdef _KERNEL
- uint8_t fpua[sizeof (kfpu_t) + GSR_SIZE + VIS_ALIGN];
kfpu_t *fpu;
-
- uint32_t len = (input_len + buf_index) & ~0x3f;
- int svfp_ok;
-
- fpu = (kfpu_t *)P2ROUNDUP((uintptr_t)fpua, 64);
- svfp_ok = ((len >= vis_sha1_svfp_threshold) ? 1 : 0);
- usevis = fpu_exists && sha1_savefp(fpu, svfp_ok);
-#else
- if (!checked_vis)
- usevis = havevis();
+ if (fpu_exists) {
+ uint8_t fpua[sizeof (kfpu_t) + GSR_SIZE + VIS_ALIGN];
+ uint32_t len = (input_len + buf_index) & ~0x3f;
+ int svfp_ok;
+
+ fpu = (kfpu_t *)P2ROUNDUP((uintptr_t)fpua, 64);
+ svfp_ok = ((len >= vis_sha1_svfp_threshold) ? 1 : 0);
+ usevis = fpu_exists && sha1_savefp(fpu, svfp_ok);
+ } else {
+ usevis = 0;
+ }
#endif /* _KERNEL */
/*
@@ -485,12 +235,10 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
bcopy(input, &ctx->buf_un.buf8[buf_index], buf_len);
if (usevis) {
SHA1TransformVIS(X0,
- (uint64_t *)ctx->buf_un.buf8,
+ ctx->buf_un.buf32,
&ctx->state[0], VIS);
} else {
- SHA1Transform(ctx->state[0], ctx->state[1],
- ctx->state[2], ctx->state[3],
- ctx->state[4], ctx, ctx->buf_un.buf8);
+ SHA1_TRANSFORM(ctx, ctx->buf_un.buf8);
}
i = buf_len;
}
@@ -510,7 +258,7 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
*
* void SHA1TransformVIS(
* uint64_t *, // Pointer to MS for ith block
- * uint64_t *, // Pointer to ith block of message data
+ * uint32_t *, // Pointer to ith block of message data
* uint32_t *, // Pointer to SHA state i.e ctx->state
* uint64_t *, // Pointer to various VIS constants
* )
@@ -524,13 +272,13 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
* for alignments other than 4-bytes.
*/
if (usevis) {
- if (((uint64_t)(uintptr_t)(&input[i]) & 0x3)) {
+ if (!IS_P2ALIGNED(&input[i], sizeof (uint32_t))) {
/*
* Main processing loop - input misaligned
*/
for (; i + 63 < input_len; i += 64) {
bcopy(&input[i], input64, 64);
- SHA1TransformVIS(X0, input64,
+ SHA1TransformVIS(X0, (uint32_t *)input64,
&ctx->state[0], VIS);
}
} else {
@@ -539,7 +287,8 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
*/
for (; i + 63 < input_len; i += 64) {
SHA1TransformVIS(X0,
- (uint64_t *)&input[i],
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
+ (uint32_t *)&input[i],
&ctx->state[0], VIS);
}
@@ -549,9 +298,7 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
#endif /* _KERNEL */
} else {
for (; i + 63 < input_len; i += 64) {
- SHA1Transform(ctx->state[0], ctx->state[1],
- ctx->state[2], ctx->state[3], ctx->state[4],
- ctx, &input[i]);
+ SHA1_TRANSFORM(ctx, &input[i]);
}
}
@@ -576,9 +323,10 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
#else /* VIS_SHA1 */
void
-SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
+SHA1Update(SHA1_CTX *ctx, const void *inptr, size_t input_len)
{
uint32_t i, buf_index, buf_len;
+ const uint8_t *input = inptr;
/* check for noop */
if (input_len == 0)
@@ -611,19 +359,12 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
if (buf_index) {
bcopy(input, &ctx->buf_un.buf8[buf_index], buf_len);
-
-
- SHA1Transform(ctx->state[0], ctx->state[1],
- ctx->state[2], ctx->state[3], ctx->state[4], ctx,
- ctx->buf_un.buf8);
-
+ SHA1_TRANSFORM(ctx, ctx->buf_un.buf8);
i = buf_len;
}
for (; i + 63 < input_len; i += 64)
- SHA1Transform(ctx->state[0], ctx->state[1],
- ctx->state[2], ctx->state[3], ctx->state[4],
- ctx, &input[i]);
+ SHA1_TRANSFORM(ctx, &input[i]);
/*
* general optimization:
@@ -656,7 +397,7 @@ SHA1Update(SHA1_CTX *ctx, const uint8_t *input, uint32_t input_len)
*/
void
-SHA1Final(uint8_t *digest, SHA1_CTX *ctx)
+SHA1Final(void *digest, SHA1_CTX *ctx)
{
uint8_t bitcount_be[sizeof (ctx->count)];
uint32_t index = (ctx->count[1] >> 3) & 0x3f;
@@ -677,6 +418,12 @@ SHA1Final(uint8_t *digest, SHA1_CTX *ctx)
bzero(ctx, sizeof (*ctx));
}
+#if defined(__amd64)
+typedef uint64_t sha1word;
+#else
+typedef uint32_t sha1word;
+#endif
+
/*
* sparc optimization:
*
@@ -690,11 +437,33 @@ SHA1Final(uint8_t *digest, SHA1_CTX *ctx)
#define LOAD_BIG_32(addr) (*(uint32_t *)(addr))
-#else /* little endian -- will work on big endian, but slowly */
+#else /* !defined(_BIG_ENDIAN) */
+
+#if defined(HAVE_BSWAP)
+#define LOAD_BIG_32(addr) bswap(*((uint32_t *)(addr)))
+
+#else /* !defined(HAVE_BSWAP) */
+
+/* little endian -- will work on big endian, but slowly */
#define LOAD_BIG_32(addr) \
(((addr)[0] << 24) | ((addr)[1] << 16) | ((addr)[2] << 8) | (addr)[3])
-#endif
+
+#endif /* !defined(HAVE_BSWAP) */
+
+#endif /* !defined(_BIG_ENDIAN) */
+
+/*
+ * SHA1Transform()
+ */
+#if defined(W_ARRAY)
+#define W(n) w[n]
+#else /* !defined(W_ARRAY) */
+#define W(n) w_ ## n
+#endif /* !defined(W_ARRAY) */
+
+
+#if defined(__sparc)
/*
* sparc register window optimization:
@@ -703,10 +472,6 @@ SHA1Final(uint8_t *digest, SHA1_CTX *ctx)
* explicitly since it increases the number of registers available to
* the compiler. under this scheme, these variables can be held in
* %i0 - %i4, which leaves more local and out registers available.
- */
-
-/*
- * SHA1Transform()
*
* purpose: sha1 transformation -- updates the digest based on `block'
* input: uint32_t : bytes 1 - 4 of the digest
@@ -757,11 +522,9 @@ SHA1Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
* depending on what platform this code is compiled for.
*/
-#if defined(__sparc)
static const uint32_t sha1_consts[] = {
SHA1_CONST_0, SHA1_CONST_1, SHA1_CONST_2, SHA1_CONST_3,
};
-#endif
/*
* general optimization:
@@ -791,7 +554,6 @@ SHA1Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
* *does not* like that, so please resist the urge.
*/
-#if defined(__sparc)
if ((uintptr_t)blk & 0x3) { /* not 4-byte aligned? */
bcopy(blk, ctx->buf_un.buf32, sizeof (ctx->buf_un.buf32));
w_15 = LOAD_BIG_32(ctx->buf_un.buf32 + 15);
@@ -844,24 +606,43 @@ SHA1Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
/*LINTED*/
w_0 = LOAD_BIG_32(blk + 0);
}
-#else
- w_15 = LOAD_BIG_32(blk + 60);
- w_14 = LOAD_BIG_32(blk + 56);
- w_13 = LOAD_BIG_32(blk + 52);
- w_12 = LOAD_BIG_32(blk + 48);
- w_11 = LOAD_BIG_32(blk + 44);
- w_10 = LOAD_BIG_32(blk + 40);
- w_9 = LOAD_BIG_32(blk + 36);
- w_8 = LOAD_BIG_32(blk + 32);
- w_7 = LOAD_BIG_32(blk + 28);
- w_6 = LOAD_BIG_32(blk + 24);
- w_5 = LOAD_BIG_32(blk + 20);
- w_4 = LOAD_BIG_32(blk + 16);
- w_3 = LOAD_BIG_32(blk + 12);
- w_2 = LOAD_BIG_32(blk + 8);
- w_1 = LOAD_BIG_32(blk + 4);
- w_0 = LOAD_BIG_32(blk + 0);
-#endif
+#else /* !defined(__sparc) */
+
+void
+SHA1Transform(SHA1_CTX *ctx, const uint8_t blk[64])
+{
+ sha1word a = ctx->state[0];
+ sha1word b = ctx->state[1];
+ sha1word c = ctx->state[2];
+ sha1word d = ctx->state[3];
+ sha1word e = ctx->state[4];
+
+#if defined(W_ARRAY)
+ sha1word w[16];
+#else /* !defined(W_ARRAY) */
+ sha1word w_0, w_1, w_2, w_3, w_4, w_5, w_6, w_7;
+ sha1word w_8, w_9, w_10, w_11, w_12, w_13, w_14, w_15;
+#endif /* !defined(W_ARRAY) */
+
+ W(0) = LOAD_BIG_32(blk + 0);
+ W(1) = LOAD_BIG_32(blk + 4);
+ W(2) = LOAD_BIG_32(blk + 8);
+ W(3) = LOAD_BIG_32(blk + 12);
+ W(4) = LOAD_BIG_32(blk + 16);
+ W(5) = LOAD_BIG_32(blk + 20);
+ W(6) = LOAD_BIG_32(blk + 24);
+ W(7) = LOAD_BIG_32(blk + 28);
+ W(8) = LOAD_BIG_32(blk + 32);
+ W(9) = LOAD_BIG_32(blk + 36);
+ W(10) = LOAD_BIG_32(blk + 40);
+ W(11) = LOAD_BIG_32(blk + 44);
+ W(12) = LOAD_BIG_32(blk + 48);
+ W(13) = LOAD_BIG_32(blk + 52);
+ W(14) = LOAD_BIG_32(blk + 56);
+ W(15) = LOAD_BIG_32(blk + 60);
+
+#endif /* !defined(__sparc) */
+
/*
* general optimization:
*
@@ -887,312 +668,312 @@ SHA1Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
*/
/* round 1 */
- e = ROTATE_LEFT(a, 5) + F(b, c, d) + e + w_0 + SHA1_CONST(0); /* 0 */
+ e = ROTATE_LEFT(a, 5) + F(b, c, d) + e + W(0) + SHA1_CONST(0); /* 0 */
b = ROTATE_LEFT(b, 30);
- d = ROTATE_LEFT(e, 5) + F(a, b, c) + d + w_1 + SHA1_CONST(0); /* 1 */
+ d = ROTATE_LEFT(e, 5) + F(a, b, c) + d + W(1) + SHA1_CONST(0); /* 1 */
a = ROTATE_LEFT(a, 30);
- c = ROTATE_LEFT(d, 5) + F(e, a, b) + c + w_2 + SHA1_CONST(0); /* 2 */
+ c = ROTATE_LEFT(d, 5) + F(e, a, b) + c + W(2) + SHA1_CONST(0); /* 2 */
e = ROTATE_LEFT(e, 30);
- b = ROTATE_LEFT(c, 5) + F(d, e, a) + b + w_3 + SHA1_CONST(0); /* 3 */
+ b = ROTATE_LEFT(c, 5) + F(d, e, a) + b + W(3) + SHA1_CONST(0); /* 3 */
d = ROTATE_LEFT(d, 30);
- a = ROTATE_LEFT(b, 5) + F(c, d, e) + a + w_4 + SHA1_CONST(0); /* 4 */
+ a = ROTATE_LEFT(b, 5) + F(c, d, e) + a + W(4) + SHA1_CONST(0); /* 4 */
c = ROTATE_LEFT(c, 30);
- e = ROTATE_LEFT(a, 5) + F(b, c, d) + e + w_5 + SHA1_CONST(0); /* 5 */
+ e = ROTATE_LEFT(a, 5) + F(b, c, d) + e + W(5) + SHA1_CONST(0); /* 5 */
b = ROTATE_LEFT(b, 30);
- d = ROTATE_LEFT(e, 5) + F(a, b, c) + d + w_6 + SHA1_CONST(0); /* 6 */
+ d = ROTATE_LEFT(e, 5) + F(a, b, c) + d + W(6) + SHA1_CONST(0); /* 6 */
a = ROTATE_LEFT(a, 30);
- c = ROTATE_LEFT(d, 5) + F(e, a, b) + c + w_7 + SHA1_CONST(0); /* 7 */
+ c = ROTATE_LEFT(d, 5) + F(e, a, b) + c + W(7) + SHA1_CONST(0); /* 7 */
e = ROTATE_LEFT(e, 30);
- b = ROTATE_LEFT(c, 5) + F(d, e, a) + b + w_8 + SHA1_CONST(0); /* 8 */
+ b = ROTATE_LEFT(c, 5) + F(d, e, a) + b + W(8) + SHA1_CONST(0); /* 8 */
d = ROTATE_LEFT(d, 30);
- a = ROTATE_LEFT(b, 5) + F(c, d, e) + a + w_9 + SHA1_CONST(0); /* 9 */
+ a = ROTATE_LEFT(b, 5) + F(c, d, e) + a + W(9) + SHA1_CONST(0); /* 9 */
c = ROTATE_LEFT(c, 30);
- e = ROTATE_LEFT(a, 5) + F(b, c, d) + e + w_10 + SHA1_CONST(0); /* 10 */
+ e = ROTATE_LEFT(a, 5) + F(b, c, d) + e + W(10) + SHA1_CONST(0); /* 10 */
b = ROTATE_LEFT(b, 30);
- d = ROTATE_LEFT(e, 5) + F(a, b, c) + d + w_11 + SHA1_CONST(0); /* 11 */
+ d = ROTATE_LEFT(e, 5) + F(a, b, c) + d + W(11) + SHA1_CONST(0); /* 11 */
a = ROTATE_LEFT(a, 30);
- c = ROTATE_LEFT(d, 5) + F(e, a, b) + c + w_12 + SHA1_CONST(0); /* 12 */
+ c = ROTATE_LEFT(d, 5) + F(e, a, b) + c + W(12) + SHA1_CONST(0); /* 12 */
e = ROTATE_LEFT(e, 30);
- b = ROTATE_LEFT(c, 5) + F(d, e, a) + b + w_13 + SHA1_CONST(0); /* 13 */
+ b = ROTATE_LEFT(c, 5) + F(d, e, a) + b + W(13) + SHA1_CONST(0); /* 13 */
d = ROTATE_LEFT(d, 30);
- a = ROTATE_LEFT(b, 5) + F(c, d, e) + a + w_14 + SHA1_CONST(0); /* 14 */
+ a = ROTATE_LEFT(b, 5) + F(c, d, e) + a + W(14) + SHA1_CONST(0); /* 14 */
c = ROTATE_LEFT(c, 30);
- e = ROTATE_LEFT(a, 5) + F(b, c, d) + e + w_15 + SHA1_CONST(0); /* 15 */
+ e = ROTATE_LEFT(a, 5) + F(b, c, d) + e + W(15) + SHA1_CONST(0); /* 15 */
b = ROTATE_LEFT(b, 30);
- w_0 = ROTATE_LEFT((w_13 ^ w_8 ^ w_2 ^ w_0), 1); /* 16 */
- d = ROTATE_LEFT(e, 5) + F(a, b, c) + d + w_0 + SHA1_CONST(0);
+ W(0) = ROTATE_LEFT((W(13) ^ W(8) ^ W(2) ^ W(0)), 1); /* 16 */
+ d = ROTATE_LEFT(e, 5) + F(a, b, c) + d + W(0) + SHA1_CONST(0);
a = ROTATE_LEFT(a, 30);
- w_1 = ROTATE_LEFT((w_14 ^ w_9 ^ w_3 ^ w_1), 1); /* 17 */
- c = ROTATE_LEFT(d, 5) + F(e, a, b) + c + w_1 + SHA1_CONST(0);
+ W(1) = ROTATE_LEFT((W(14) ^ W(9) ^ W(3) ^ W(1)), 1); /* 17 */
+ c = ROTATE_LEFT(d, 5) + F(e, a, b) + c + W(1) + SHA1_CONST(0);
e = ROTATE_LEFT(e, 30);
- w_2 = ROTATE_LEFT((w_15 ^ w_10 ^ w_4 ^ w_2), 1); /* 18 */
- b = ROTATE_LEFT(c, 5) + F(d, e, a) + b + w_2 + SHA1_CONST(0);
+ W(2) = ROTATE_LEFT((W(15) ^ W(10) ^ W(4) ^ W(2)), 1); /* 18 */
+ b = ROTATE_LEFT(c, 5) + F(d, e, a) + b + W(2) + SHA1_CONST(0);
d = ROTATE_LEFT(d, 30);
- w_3 = ROTATE_LEFT((w_0 ^ w_11 ^ w_5 ^ w_3), 1); /* 19 */
- a = ROTATE_LEFT(b, 5) + F(c, d, e) + a + w_3 + SHA1_CONST(0);
+ W(3) = ROTATE_LEFT((W(0) ^ W(11) ^ W(5) ^ W(3)), 1); /* 19 */
+ a = ROTATE_LEFT(b, 5) + F(c, d, e) + a + W(3) + SHA1_CONST(0);
c = ROTATE_LEFT(c, 30);
/* round 2 */
- w_4 = ROTATE_LEFT((w_1 ^ w_12 ^ w_6 ^ w_4), 1); /* 20 */
- e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + w_4 + SHA1_CONST(1);
+ W(4) = ROTATE_LEFT((W(1) ^ W(12) ^ W(6) ^ W(4)), 1); /* 20 */
+ e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + W(4) + SHA1_CONST(1);
b = ROTATE_LEFT(b, 30);
- w_5 = ROTATE_LEFT((w_2 ^ w_13 ^ w_7 ^ w_5), 1); /* 21 */
- d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + w_5 + SHA1_CONST(1);
+ W(5) = ROTATE_LEFT((W(2) ^ W(13) ^ W(7) ^ W(5)), 1); /* 21 */
+ d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + W(5) + SHA1_CONST(1);
a = ROTATE_LEFT(a, 30);
- w_6 = ROTATE_LEFT((w_3 ^ w_14 ^ w_8 ^ w_6), 1); /* 22 */
- c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + w_6 + SHA1_CONST(1);
+ W(6) = ROTATE_LEFT((W(3) ^ W(14) ^ W(8) ^ W(6)), 1); /* 22 */
+ c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + W(6) + SHA1_CONST(1);
e = ROTATE_LEFT(e, 30);
- w_7 = ROTATE_LEFT((w_4 ^ w_15 ^ w_9 ^ w_7), 1); /* 23 */
- b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + w_7 + SHA1_CONST(1);
+ W(7) = ROTATE_LEFT((W(4) ^ W(15) ^ W(9) ^ W(7)), 1); /* 23 */
+ b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + W(7) + SHA1_CONST(1);
d = ROTATE_LEFT(d, 30);
- w_8 = ROTATE_LEFT((w_5 ^ w_0 ^ w_10 ^ w_8), 1); /* 24 */
- a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + w_8 + SHA1_CONST(1);
+ W(8) = ROTATE_LEFT((W(5) ^ W(0) ^ W(10) ^ W(8)), 1); /* 24 */
+ a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + W(8) + SHA1_CONST(1);
c = ROTATE_LEFT(c, 30);
- w_9 = ROTATE_LEFT((w_6 ^ w_1 ^ w_11 ^ w_9), 1); /* 25 */
- e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + w_9 + SHA1_CONST(1);
+ W(9) = ROTATE_LEFT((W(6) ^ W(1) ^ W(11) ^ W(9)), 1); /* 25 */
+ e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + W(9) + SHA1_CONST(1);
b = ROTATE_LEFT(b, 30);
- w_10 = ROTATE_LEFT((w_7 ^ w_2 ^ w_12 ^ w_10), 1); /* 26 */
- d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + w_10 + SHA1_CONST(1);
+ W(10) = ROTATE_LEFT((W(7) ^ W(2) ^ W(12) ^ W(10)), 1); /* 26 */
+ d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + W(10) + SHA1_CONST(1);
a = ROTATE_LEFT(a, 30);
- w_11 = ROTATE_LEFT((w_8 ^ w_3 ^ w_13 ^ w_11), 1); /* 27 */
- c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + w_11 + SHA1_CONST(1);
+ W(11) = ROTATE_LEFT((W(8) ^ W(3) ^ W(13) ^ W(11)), 1); /* 27 */
+ c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + W(11) + SHA1_CONST(1);
e = ROTATE_LEFT(e, 30);
- w_12 = ROTATE_LEFT((w_9 ^ w_4 ^ w_14 ^ w_12), 1); /* 28 */
- b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + w_12 + SHA1_CONST(1);
+ W(12) = ROTATE_LEFT((W(9) ^ W(4) ^ W(14) ^ W(12)), 1); /* 28 */
+ b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + W(12) + SHA1_CONST(1);
d = ROTATE_LEFT(d, 30);
- w_13 = ROTATE_LEFT((w_10 ^ w_5 ^ w_15 ^ w_13), 1); /* 29 */
- a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + w_13 + SHA1_CONST(1);
+ W(13) = ROTATE_LEFT((W(10) ^ W(5) ^ W(15) ^ W(13)), 1); /* 29 */
+ a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + W(13) + SHA1_CONST(1);
c = ROTATE_LEFT(c, 30);
- w_14 = ROTATE_LEFT((w_11 ^ w_6 ^ w_0 ^ w_14), 1); /* 30 */
- e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + w_14 + SHA1_CONST(1);
+ W(14) = ROTATE_LEFT((W(11) ^ W(6) ^ W(0) ^ W(14)), 1); /* 30 */
+ e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + W(14) + SHA1_CONST(1);
b = ROTATE_LEFT(b, 30);
- w_15 = ROTATE_LEFT((w_12 ^ w_7 ^ w_1 ^ w_15), 1); /* 31 */
- d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + w_15 + SHA1_CONST(1);
+ W(15) = ROTATE_LEFT((W(12) ^ W(7) ^ W(1) ^ W(15)), 1); /* 31 */
+ d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + W(15) + SHA1_CONST(1);
a = ROTATE_LEFT(a, 30);
- w_0 = ROTATE_LEFT((w_13 ^ w_8 ^ w_2 ^ w_0), 1); /* 32 */
- c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + w_0 + SHA1_CONST(1);
+ W(0) = ROTATE_LEFT((W(13) ^ W(8) ^ W(2) ^ W(0)), 1); /* 32 */
+ c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + W(0) + SHA1_CONST(1);
e = ROTATE_LEFT(e, 30);
- w_1 = ROTATE_LEFT((w_14 ^ w_9 ^ w_3 ^ w_1), 1); /* 33 */
- b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + w_1 + SHA1_CONST(1);
+ W(1) = ROTATE_LEFT((W(14) ^ W(9) ^ W(3) ^ W(1)), 1); /* 33 */
+ b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + W(1) + SHA1_CONST(1);
d = ROTATE_LEFT(d, 30);
- w_2 = ROTATE_LEFT((w_15 ^ w_10 ^ w_4 ^ w_2), 1); /* 34 */
- a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + w_2 + SHA1_CONST(1);
+ W(2) = ROTATE_LEFT((W(15) ^ W(10) ^ W(4) ^ W(2)), 1); /* 34 */
+ a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + W(2) + SHA1_CONST(1);
c = ROTATE_LEFT(c, 30);
- w_3 = ROTATE_LEFT((w_0 ^ w_11 ^ w_5 ^ w_3), 1); /* 35 */
- e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + w_3 + SHA1_CONST(1);
+ W(3) = ROTATE_LEFT((W(0) ^ W(11) ^ W(5) ^ W(3)), 1); /* 35 */
+ e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + W(3) + SHA1_CONST(1);
b = ROTATE_LEFT(b, 30);
- w_4 = ROTATE_LEFT((w_1 ^ w_12 ^ w_6 ^ w_4), 1); /* 36 */
- d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + w_4 + SHA1_CONST(1);
+ W(4) = ROTATE_LEFT((W(1) ^ W(12) ^ W(6) ^ W(4)), 1); /* 36 */
+ d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + W(4) + SHA1_CONST(1);
a = ROTATE_LEFT(a, 30);
- w_5 = ROTATE_LEFT((w_2 ^ w_13 ^ w_7 ^ w_5), 1); /* 37 */
- c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + w_5 + SHA1_CONST(1);
+ W(5) = ROTATE_LEFT((W(2) ^ W(13) ^ W(7) ^ W(5)), 1); /* 37 */
+ c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + W(5) + SHA1_CONST(1);
e = ROTATE_LEFT(e, 30);
- w_6 = ROTATE_LEFT((w_3 ^ w_14 ^ w_8 ^ w_6), 1); /* 38 */
- b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + w_6 + SHA1_CONST(1);
+ W(6) = ROTATE_LEFT((W(3) ^ W(14) ^ W(8) ^ W(6)), 1); /* 38 */
+ b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + W(6) + SHA1_CONST(1);
d = ROTATE_LEFT(d, 30);
- w_7 = ROTATE_LEFT((w_4 ^ w_15 ^ w_9 ^ w_7), 1); /* 39 */
- a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + w_7 + SHA1_CONST(1);
+ W(7) = ROTATE_LEFT((W(4) ^ W(15) ^ W(9) ^ W(7)), 1); /* 39 */
+ a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + W(7) + SHA1_CONST(1);
c = ROTATE_LEFT(c, 30);
/* round 3 */
- w_8 = ROTATE_LEFT((w_5 ^ w_0 ^ w_10 ^ w_8), 1); /* 40 */
- e = ROTATE_LEFT(a, 5) + H(b, c, d) + e + w_8 + SHA1_CONST(2);
+ W(8) = ROTATE_LEFT((W(5) ^ W(0) ^ W(10) ^ W(8)), 1); /* 40 */
+ e = ROTATE_LEFT(a, 5) + H(b, c, d) + e + W(8) + SHA1_CONST(2);
b = ROTATE_LEFT(b, 30);
- w_9 = ROTATE_LEFT((w_6 ^ w_1 ^ w_11 ^ w_9), 1); /* 41 */
- d = ROTATE_LEFT(e, 5) + H(a, b, c) + d + w_9 + SHA1_CONST(2);
+ W(9) = ROTATE_LEFT((W(6) ^ W(1) ^ W(11) ^ W(9)), 1); /* 41 */
+ d = ROTATE_LEFT(e, 5) + H(a, b, c) + d + W(9) + SHA1_CONST(2);
a = ROTATE_LEFT(a, 30);
- w_10 = ROTATE_LEFT((w_7 ^ w_2 ^ w_12 ^ w_10), 1); /* 42 */
- c = ROTATE_LEFT(d, 5) + H(e, a, b) + c + w_10 + SHA1_CONST(2);
+ W(10) = ROTATE_LEFT((W(7) ^ W(2) ^ W(12) ^ W(10)), 1); /* 42 */
+ c = ROTATE_LEFT(d, 5) + H(e, a, b) + c + W(10) + SHA1_CONST(2);
e = ROTATE_LEFT(e, 30);
- w_11 = ROTATE_LEFT((w_8 ^ w_3 ^ w_13 ^ w_11), 1); /* 43 */
- b = ROTATE_LEFT(c, 5) + H(d, e, a) + b + w_11 + SHA1_CONST(2);
+ W(11) = ROTATE_LEFT((W(8) ^ W(3) ^ W(13) ^ W(11)), 1); /* 43 */
+ b = ROTATE_LEFT(c, 5) + H(d, e, a) + b + W(11) + SHA1_CONST(2);
d = ROTATE_LEFT(d, 30);
- w_12 = ROTATE_LEFT((w_9 ^ w_4 ^ w_14 ^ w_12), 1); /* 44 */
- a = ROTATE_LEFT(b, 5) + H(c, d, e) + a + w_12 + SHA1_CONST(2);
+ W(12) = ROTATE_LEFT((W(9) ^ W(4) ^ W(14) ^ W(12)), 1); /* 44 */
+ a = ROTATE_LEFT(b, 5) + H(c, d, e) + a + W(12) + SHA1_CONST(2);
c = ROTATE_LEFT(c, 30);
- w_13 = ROTATE_LEFT((w_10 ^ w_5 ^ w_15 ^ w_13), 1); /* 45 */
- e = ROTATE_LEFT(a, 5) + H(b, c, d) + e + w_13 + SHA1_CONST(2);
+ W(13) = ROTATE_LEFT((W(10) ^ W(5) ^ W(15) ^ W(13)), 1); /* 45 */
+ e = ROTATE_LEFT(a, 5) + H(b, c, d) + e + W(13) + SHA1_CONST(2);
b = ROTATE_LEFT(b, 30);
- w_14 = ROTATE_LEFT((w_11 ^ w_6 ^ w_0 ^ w_14), 1); /* 46 */
- d = ROTATE_LEFT(e, 5) + H(a, b, c) + d + w_14 + SHA1_CONST(2);
+ W(14) = ROTATE_LEFT((W(11) ^ W(6) ^ W(0) ^ W(14)), 1); /* 46 */
+ d = ROTATE_LEFT(e, 5) + H(a, b, c) + d + W(14) + SHA1_CONST(2);
a = ROTATE_LEFT(a, 30);
- w_15 = ROTATE_LEFT((w_12 ^ w_7 ^ w_1 ^ w_15), 1); /* 47 */
- c = ROTATE_LEFT(d, 5) + H(e, a, b) + c + w_15 + SHA1_CONST(2);
+ W(15) = ROTATE_LEFT((W(12) ^ W(7) ^ W(1) ^ W(15)), 1); /* 47 */
+ c = ROTATE_LEFT(d, 5) + H(e, a, b) + c + W(15) + SHA1_CONST(2);
e = ROTATE_LEFT(e, 30);
- w_0 = ROTATE_LEFT((w_13 ^ w_8 ^ w_2 ^ w_0), 1); /* 48 */
- b = ROTATE_LEFT(c, 5) + H(d, e, a) + b + w_0 + SHA1_CONST(2);
+ W(0) = ROTATE_LEFT((W(13) ^ W(8) ^ W(2) ^ W(0)), 1); /* 48 */
+ b = ROTATE_LEFT(c, 5) + H(d, e, a) + b + W(0) + SHA1_CONST(2);
d = ROTATE_LEFT(d, 30);
- w_1 = ROTATE_LEFT((w_14 ^ w_9 ^ w_3 ^ w_1), 1); /* 49 */
- a = ROTATE_LEFT(b, 5) + H(c, d, e) + a + w_1 + SHA1_CONST(2);
+ W(1) = ROTATE_LEFT((W(14) ^ W(9) ^ W(3) ^ W(1)), 1); /* 49 */
+ a = ROTATE_LEFT(b, 5) + H(c, d, e) + a + W(1) + SHA1_CONST(2);
c = ROTATE_LEFT(c, 30);
- w_2 = ROTATE_LEFT((w_15 ^ w_10 ^ w_4 ^ w_2), 1); /* 50 */
- e = ROTATE_LEFT(a, 5) + H(b, c, d) + e + w_2 + SHA1_CONST(2);
+ W(2) = ROTATE_LEFT((W(15) ^ W(10) ^ W(4) ^ W(2)), 1); /* 50 */
+ e = ROTATE_LEFT(a, 5) + H(b, c, d) + e + W(2) + SHA1_CONST(2);
b = ROTATE_LEFT(b, 30);
- w_3 = ROTATE_LEFT((w_0 ^ w_11 ^ w_5 ^ w_3), 1); /* 51 */
- d = ROTATE_LEFT(e, 5) + H(a, b, c) + d + w_3 + SHA1_CONST(2);
+ W(3) = ROTATE_LEFT((W(0) ^ W(11) ^ W(5) ^ W(3)), 1); /* 51 */
+ d = ROTATE_LEFT(e, 5) + H(a, b, c) + d + W(3) + SHA1_CONST(2);
a = ROTATE_LEFT(a, 30);
- w_4 = ROTATE_LEFT((w_1 ^ w_12 ^ w_6 ^ w_4), 1); /* 52 */
- c = ROTATE_LEFT(d, 5) + H(e, a, b) + c + w_4 + SHA1_CONST(2);
+ W(4) = ROTATE_LEFT((W(1) ^ W(12) ^ W(6) ^ W(4)), 1); /* 52 */
+ c = ROTATE_LEFT(d, 5) + H(e, a, b) + c + W(4) + SHA1_CONST(2);
e = ROTATE_LEFT(e, 30);
- w_5 = ROTATE_LEFT((w_2 ^ w_13 ^ w_7 ^ w_5), 1); /* 53 */
- b = ROTATE_LEFT(c, 5) + H(d, e, a) + b + w_5 + SHA1_CONST(2);
+ W(5) = ROTATE_LEFT((W(2) ^ W(13) ^ W(7) ^ W(5)), 1); /* 53 */
+ b = ROTATE_LEFT(c, 5) + H(d, e, a) + b + W(5) + SHA1_CONST(2);
d = ROTATE_LEFT(d, 30);
- w_6 = ROTATE_LEFT((w_3 ^ w_14 ^ w_8 ^ w_6), 1); /* 54 */
- a = ROTATE_LEFT(b, 5) + H(c, d, e) + a + w_6 + SHA1_CONST(2);
+ W(6) = ROTATE_LEFT((W(3) ^ W(14) ^ W(8) ^ W(6)), 1); /* 54 */
+ a = ROTATE_LEFT(b, 5) + H(c, d, e) + a + W(6) + SHA1_CONST(2);
c = ROTATE_LEFT(c, 30);
- w_7 = ROTATE_LEFT((w_4 ^ w_15 ^ w_9 ^ w_7), 1); /* 55 */
- e = ROTATE_LEFT(a, 5) + H(b, c, d) + e + w_7 + SHA1_CONST(2);
+ W(7) = ROTATE_LEFT((W(4) ^ W(15) ^ W(9) ^ W(7)), 1); /* 55 */
+ e = ROTATE_LEFT(a, 5) + H(b, c, d) + e + W(7) + SHA1_CONST(2);
b = ROTATE_LEFT(b, 30);
- w_8 = ROTATE_LEFT((w_5 ^ w_0 ^ w_10 ^ w_8), 1); /* 56 */
- d = ROTATE_LEFT(e, 5) + H(a, b, c) + d + w_8 + SHA1_CONST(2);
+ W(8) = ROTATE_LEFT((W(5) ^ W(0) ^ W(10) ^ W(8)), 1); /* 56 */
+ d = ROTATE_LEFT(e, 5) + H(a, b, c) + d + W(8) + SHA1_CONST(2);
a = ROTATE_LEFT(a, 30);
- w_9 = ROTATE_LEFT((w_6 ^ w_1 ^ w_11 ^ w_9), 1); /* 57 */
- c = ROTATE_LEFT(d, 5) + H(e, a, b) + c + w_9 + SHA1_CONST(2);
+ W(9) = ROTATE_LEFT((W(6) ^ W(1) ^ W(11) ^ W(9)), 1); /* 57 */
+ c = ROTATE_LEFT(d, 5) + H(e, a, b) + c + W(9) + SHA1_CONST(2);
e = ROTATE_LEFT(e, 30);
- w_10 = ROTATE_LEFT((w_7 ^ w_2 ^ w_12 ^ w_10), 1); /* 58 */
- b = ROTATE_LEFT(c, 5) + H(d, e, a) + b + w_10 + SHA1_CONST(2);
+ W(10) = ROTATE_LEFT((W(7) ^ W(2) ^ W(12) ^ W(10)), 1); /* 58 */
+ b = ROTATE_LEFT(c, 5) + H(d, e, a) + b + W(10) + SHA1_CONST(2);
d = ROTATE_LEFT(d, 30);
- w_11 = ROTATE_LEFT((w_8 ^ w_3 ^ w_13 ^ w_11), 1); /* 59 */
- a = ROTATE_LEFT(b, 5) + H(c, d, e) + a + w_11 + SHA1_CONST(2);
+ W(11) = ROTATE_LEFT((W(8) ^ W(3) ^ W(13) ^ W(11)), 1); /* 59 */
+ a = ROTATE_LEFT(b, 5) + H(c, d, e) + a + W(11) + SHA1_CONST(2);
c = ROTATE_LEFT(c, 30);
/* round 4 */
- w_12 = ROTATE_LEFT((w_9 ^ w_4 ^ w_14 ^ w_12), 1); /* 60 */
- e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + w_12 + SHA1_CONST(3);
+ W(12) = ROTATE_LEFT((W(9) ^ W(4) ^ W(14) ^ W(12)), 1); /* 60 */
+ e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + W(12) + SHA1_CONST(3);
b = ROTATE_LEFT(b, 30);
- w_13 = ROTATE_LEFT((w_10 ^ w_5 ^ w_15 ^ w_13), 1); /* 61 */
- d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + w_13 + SHA1_CONST(3);
+ W(13) = ROTATE_LEFT((W(10) ^ W(5) ^ W(15) ^ W(13)), 1); /* 61 */
+ d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + W(13) + SHA1_CONST(3);
a = ROTATE_LEFT(a, 30);
- w_14 = ROTATE_LEFT((w_11 ^ w_6 ^ w_0 ^ w_14), 1); /* 62 */
- c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + w_14 + SHA1_CONST(3);
+ W(14) = ROTATE_LEFT((W(11) ^ W(6) ^ W(0) ^ W(14)), 1); /* 62 */
+ c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + W(14) + SHA1_CONST(3);
e = ROTATE_LEFT(e, 30);
- w_15 = ROTATE_LEFT((w_12 ^ w_7 ^ w_1 ^ w_15), 1); /* 63 */
- b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + w_15 + SHA1_CONST(3);
+ W(15) = ROTATE_LEFT((W(12) ^ W(7) ^ W(1) ^ W(15)), 1); /* 63 */
+ b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + W(15) + SHA1_CONST(3);
d = ROTATE_LEFT(d, 30);
- w_0 = ROTATE_LEFT((w_13 ^ w_8 ^ w_2 ^ w_0), 1); /* 64 */
- a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + w_0 + SHA1_CONST(3);
+ W(0) = ROTATE_LEFT((W(13) ^ W(8) ^ W(2) ^ W(0)), 1); /* 64 */
+ a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + W(0) + SHA1_CONST(3);
c = ROTATE_LEFT(c, 30);
- w_1 = ROTATE_LEFT((w_14 ^ w_9 ^ w_3 ^ w_1), 1); /* 65 */
- e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + w_1 + SHA1_CONST(3);
+ W(1) = ROTATE_LEFT((W(14) ^ W(9) ^ W(3) ^ W(1)), 1); /* 65 */
+ e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + W(1) + SHA1_CONST(3);
b = ROTATE_LEFT(b, 30);
- w_2 = ROTATE_LEFT((w_15 ^ w_10 ^ w_4 ^ w_2), 1); /* 66 */
- d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + w_2 + SHA1_CONST(3);
+ W(2) = ROTATE_LEFT((W(15) ^ W(10) ^ W(4) ^ W(2)), 1); /* 66 */
+ d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + W(2) + SHA1_CONST(3);
a = ROTATE_LEFT(a, 30);
- w_3 = ROTATE_LEFT((w_0 ^ w_11 ^ w_5 ^ w_3), 1); /* 67 */
- c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + w_3 + SHA1_CONST(3);
+ W(3) = ROTATE_LEFT((W(0) ^ W(11) ^ W(5) ^ W(3)), 1); /* 67 */
+ c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + W(3) + SHA1_CONST(3);
e = ROTATE_LEFT(e, 30);
- w_4 = ROTATE_LEFT((w_1 ^ w_12 ^ w_6 ^ w_4), 1); /* 68 */
- b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + w_4 + SHA1_CONST(3);
+ W(4) = ROTATE_LEFT((W(1) ^ W(12) ^ W(6) ^ W(4)), 1); /* 68 */
+ b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + W(4) + SHA1_CONST(3);
d = ROTATE_LEFT(d, 30);
- w_5 = ROTATE_LEFT((w_2 ^ w_13 ^ w_7 ^ w_5), 1); /* 69 */
- a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + w_5 + SHA1_CONST(3);
+ W(5) = ROTATE_LEFT((W(2) ^ W(13) ^ W(7) ^ W(5)), 1); /* 69 */
+ a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + W(5) + SHA1_CONST(3);
c = ROTATE_LEFT(c, 30);
- w_6 = ROTATE_LEFT((w_3 ^ w_14 ^ w_8 ^ w_6), 1); /* 70 */
- e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + w_6 + SHA1_CONST(3);
+ W(6) = ROTATE_LEFT((W(3) ^ W(14) ^ W(8) ^ W(6)), 1); /* 70 */
+ e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + W(6) + SHA1_CONST(3);
b = ROTATE_LEFT(b, 30);
- w_7 = ROTATE_LEFT((w_4 ^ w_15 ^ w_9 ^ w_7), 1); /* 71 */
- d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + w_7 + SHA1_CONST(3);
+ W(7) = ROTATE_LEFT((W(4) ^ W(15) ^ W(9) ^ W(7)), 1); /* 71 */
+ d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + W(7) + SHA1_CONST(3);
a = ROTATE_LEFT(a, 30);
- w_8 = ROTATE_LEFT((w_5 ^ w_0 ^ w_10 ^ w_8), 1); /* 72 */
- c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + w_8 + SHA1_CONST(3);
+ W(8) = ROTATE_LEFT((W(5) ^ W(0) ^ W(10) ^ W(8)), 1); /* 72 */
+ c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + W(8) + SHA1_CONST(3);
e = ROTATE_LEFT(e, 30);
- w_9 = ROTATE_LEFT((w_6 ^ w_1 ^ w_11 ^ w_9), 1); /* 73 */
- b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + w_9 + SHA1_CONST(3);
+ W(9) = ROTATE_LEFT((W(6) ^ W(1) ^ W(11) ^ W(9)), 1); /* 73 */
+ b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + W(9) + SHA1_CONST(3);
d = ROTATE_LEFT(d, 30);
- w_10 = ROTATE_LEFT((w_7 ^ w_2 ^ w_12 ^ w_10), 1); /* 74 */
- a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + w_10 + SHA1_CONST(3);
+ W(10) = ROTATE_LEFT((W(7) ^ W(2) ^ W(12) ^ W(10)), 1); /* 74 */
+ a = ROTATE_LEFT(b, 5) + G(c, d, e) + a + W(10) + SHA1_CONST(3);
c = ROTATE_LEFT(c, 30);
- w_11 = ROTATE_LEFT((w_8 ^ w_3 ^ w_13 ^ w_11), 1); /* 75 */
- e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + w_11 + SHA1_CONST(3);
+ W(11) = ROTATE_LEFT((W(8) ^ W(3) ^ W(13) ^ W(11)), 1); /* 75 */
+ e = ROTATE_LEFT(a, 5) + G(b, c, d) + e + W(11) + SHA1_CONST(3);
b = ROTATE_LEFT(b, 30);
- w_12 = ROTATE_LEFT((w_9 ^ w_4 ^ w_14 ^ w_12), 1); /* 76 */
- d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + w_12 + SHA1_CONST(3);
+ W(12) = ROTATE_LEFT((W(9) ^ W(4) ^ W(14) ^ W(12)), 1); /* 76 */
+ d = ROTATE_LEFT(e, 5) + G(a, b, c) + d + W(12) + SHA1_CONST(3);
a = ROTATE_LEFT(a, 30);
- w_13 = ROTATE_LEFT((w_10 ^ w_5 ^ w_15 ^ w_13), 1); /* 77 */
- c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + w_13 + SHA1_CONST(3);
+ W(13) = ROTATE_LEFT((W(10) ^ W(5) ^ W(15) ^ W(13)), 1); /* 77 */
+ c = ROTATE_LEFT(d, 5) + G(e, a, b) + c + W(13) + SHA1_CONST(3);
e = ROTATE_LEFT(e, 30);
- w_14 = ROTATE_LEFT((w_11 ^ w_6 ^ w_0 ^ w_14), 1); /* 78 */
- b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + w_14 + SHA1_CONST(3);
+ W(14) = ROTATE_LEFT((W(11) ^ W(6) ^ W(0) ^ W(14)), 1); /* 78 */
+ b = ROTATE_LEFT(c, 5) + G(d, e, a) + b + W(14) + SHA1_CONST(3);
d = ROTATE_LEFT(d, 30);
- w_15 = ROTATE_LEFT((w_12 ^ w_7 ^ w_1 ^ w_15), 1); /* 79 */
+ W(15) = ROTATE_LEFT((W(12) ^ W(7) ^ W(1) ^ W(15)), 1); /* 79 */
- ctx->state[0] += ROTATE_LEFT(b, 5) + G(c, d, e) + a + w_15 +
+ ctx->state[0] += ROTATE_LEFT(b, 5) + G(c, d, e) + a + W(15) +
SHA1_CONST(3);
ctx->state[1] += b;
ctx->state[2] += ROTATE_LEFT(c, 30);
@@ -1200,26 +981,11 @@ SHA1Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
ctx->state[4] += e;
/* zeroize sensitive information */
- w_0 = w_1 = w_2 = w_3 = w_4 = w_5 = w_6 = w_7 = w_8 = 0;
- w_9 = w_10 = w_11 = w_12 = w_13 = w_14 = w_15 = 0;
+ W(0) = W(1) = W(2) = W(3) = W(4) = W(5) = W(6) = W(7) = W(8) = 0;
+ W(9) = W(10) = W(11) = W(12) = W(13) = W(14) = W(15) = 0;
}
/*
- * devpro compiler optimization:
- *
- * the compiler can generate better code if it knows that `input' and
- * `output' do not point to the same source. there is no portable
- * way to tell the compiler this, but the sun compiler recognizes the
- * `_Restrict' keyword to indicate this condition. use it if possible.
- */
-
-#ifdef __RESTRICT
-#define restrict _Restrict
-#else
-#define restrict /* nothing */
-#endif
-
-/*
* Encode()
*
* purpose: to convert a list of numbers from little endian to big endian
@@ -1230,7 +996,8 @@ SHA1Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
*/
static void
-Encode(uint8_t *restrict output, uint32_t *restrict input, size_t len)
+Encode(uint8_t *_RESTRICT_KYWD output, const uint32_t *_RESTRICT_KYWD input,
+ size_t len)
{
size_t i, j;
@@ -1252,1224 +1019,3 @@ Encode(uint8_t *restrict output, uint32_t *restrict input, size_t len)
}
#endif
}
-
-
-#ifdef _KERNEL
-
-/*
- * KCF software provider control entry points.
- */
-/* ARGSUSED */
-static void
-sha1_provider_status(crypto_provider_handle_t provider, uint_t *status)
-{
- *status = CRYPTO_PROVIDER_READY;
-}
-
-/*
- * KCF software provider digest entry points.
- */
-
-static int
-sha1_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
- crypto_req_handle_t req)
-{
- if (mechanism->cm_type != SHA1_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /*
- * Allocate and initialize SHA1 context.
- */
- ctx->cc_provider_private = kmem_alloc(sizeof (sha1_ctx_t),
- crypto_kmflag(req));
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- PROV_SHA1_CTX(ctx)->sc_mech_type = SHA1_MECH_INFO_TYPE;
- SHA1Init(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx);
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper SHA1 digest update function for uio data.
- */
-static int
-sha1_digest_update_uio(SHA1_CTX *sha1_ctx, crypto_data_t *data)
-{
- off_t offset = data->cd_offset;
- size_t length = data->cd_length;
- uint_t vec_idx;
- size_t cur_len;
-
- /* we support only kernel buffer */
- if (data->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Jump to the first iovec containing data to be
- * digested.
- */
- for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt &&
- offset >= data->cd_uio->uio_iov[vec_idx].iov_len;
- offset -= data->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == data->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- /*
- * Now do the digesting on the iovecs.
- */
- while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) {
- cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
-
- SHA1Update(sha1_ctx,
- (uint8_t *)data->cd_uio->uio_iov[vec_idx].iov_base + offset,
- cur_len);
-
- length -= cur_len;
- vec_idx++;
- offset = 0;
- }
-
- if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) {
- /*
- * The end of the specified iovec's was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper SHA1 digest final function for uio data.
- * digest_len is the length of the desired digest. If digest_len
- * is smaller than the default SHA1 digest length, the caller
- * must pass a scratch buffer, digest_scratch, which must
- * be at least SHA1_DIGEST_LENGTH bytes.
- */
-static int
-sha1_digest_final_uio(SHA1_CTX *sha1_ctx, crypto_data_t *digest,
- ulong_t digest_len, uchar_t *digest_scratch)
-{
- off_t offset = digest->cd_offset;
- uint_t vec_idx;
-
- /* we support only kernel buffer */
- if (digest->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Jump to the first iovec containing ptr to the digest to
- * be returned.
- */
- for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len &&
- vec_idx < digest->cd_uio->uio_iovcnt;
- offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == digest->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is
- * larger than the total size of the buffers
- * it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- if (offset + digest_len <=
- digest->cd_uio->uio_iov[vec_idx].iov_len) {
- /*
- * The computed SHA1 digest will fit in the current
- * iovec.
- */
- if (digest_len != SHA1_DIGEST_LENGTH) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- SHA1Final(digest_scratch, sha1_ctx);
- bcopy(digest_scratch, (uchar_t *)digest->
- cd_uio->uio_iov[vec_idx].iov_base + offset,
- digest_len);
- } else {
- SHA1Final((uchar_t *)digest->
- cd_uio->uio_iov[vec_idx].iov_base + offset,
- sha1_ctx);
- }
- } else {
- /*
- * The computed digest will be crossing one or more iovec's.
- * This is bad performance-wise but we need to support it.
- * Allocate a small scratch buffer on the stack and
- * copy it piece meal to the specified digest iovec's.
- */
- uchar_t digest_tmp[SHA1_DIGEST_LENGTH];
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- SHA1Final(digest_tmp, sha1_ctx);
-
- while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) {
- cur_len = MIN(digest->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
- bcopy(digest_tmp + scratch_offset,
- digest->cd_uio->uio_iov[vec_idx].iov_base + offset,
- cur_len);
-
- length -= cur_len;
- vec_idx++;
- scratch_offset += cur_len;
- offset = 0;
- }
-
- if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) {
- /*
- * The end of the specified iovec's was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it
- * provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper SHA1 digest update for mblk's.
- */
-static int
-sha1_digest_update_mblk(SHA1_CTX *sha1_ctx, crypto_data_t *data)
-{
- off_t offset = data->cd_offset;
- size_t length = data->cd_length;
- mblk_t *mp;
- size_t cur_len;
-
- /*
- * Jump to the first mblk_t containing data to be digested.
- */
- for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- /*
- * Now do the digesting on the mblk chain.
- */
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- SHA1Update(sha1_ctx, mp->b_rptr + offset, cur_len);
- length -= cur_len;
- offset = 0;
- mp = mp->b_cont;
- }
-
- if (mp == NULL && length > 0) {
- /*
- * The end of the mblk was reached but the length requested
- * could not be processed, i.e. The caller requested
- * to digest more data than it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper SHA1 digest final for mblk's.
- * digest_len is the length of the desired digest. If digest_len
- * is smaller than the default SHA1 digest length, the caller
- * must pass a scratch buffer, digest_scratch, which must
- * be at least SHA1_DIGEST_LENGTH bytes.
- */
-static int
-sha1_digest_final_mblk(SHA1_CTX *sha1_ctx, crypto_data_t *digest,
- ulong_t digest_len, uchar_t *digest_scratch)
-{
- off_t offset = digest->cd_offset;
- mblk_t *mp;
-
- /*
- * Jump to the first mblk_t that will be used to store the digest.
- */
- for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- if (offset + digest_len <= MBLKL(mp)) {
- /*
- * The computed SHA1 digest will fit in the current mblk.
- * Do the SHA1Final() in-place.
- */
- if (digest_len != SHA1_DIGEST_LENGTH) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- SHA1Final(digest_scratch, sha1_ctx);
- bcopy(digest_scratch, mp->b_rptr + offset, digest_len);
- } else {
- SHA1Final(mp->b_rptr + offset, sha1_ctx);
- }
- } else {
- /*
- * The computed digest will be crossing one or more mblk's.
- * This is bad performance-wise but we need to support it.
- * Allocate a small scratch buffer on the stack and
- * copy it piece meal to the specified digest iovec's.
- */
- uchar_t digest_tmp[SHA1_DIGEST_LENGTH];
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- SHA1Final(digest_tmp, sha1_ctx);
-
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- bcopy(digest_tmp + scratch_offset,
- mp->b_rptr + offset, cur_len);
-
- length -= cur_len;
- mp = mp->b_cont;
- scratch_offset += cur_len;
- offset = 0;
- }
-
- if (mp == NULL && length > 0) {
- /*
- * The end of the specified mblk was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it
- * provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/* ARGSUSED */
-static int
-sha1_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((digest->cd_length == 0) ||
- (digest->cd_length < SHA1_DIGEST_LENGTH)) {
- digest->cd_length = SHA1_DIGEST_LENGTH;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do the SHA1 update on the specified input data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA1Update(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_update_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_update_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret != CRYPTO_SUCCESS) {
- /* the update failed, free context and bail */
- kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t));
- ctx->cc_provider_private = NULL;
- digest->cd_length = 0;
- return (ret);
- }
-
- /*
- * Do a SHA1 final, must be done separately since the digest
- * type can be different than the input data type.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA1Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &PROV_SHA1_CTX(ctx)->sc_sha1_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_final_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- digest, SHA1_DIGEST_LENGTH, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_final_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- digest, SHA1_DIGEST_LENGTH, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- /* all done, free context and return */
-
- if (ret == CRYPTO_SUCCESS) {
- digest->cd_length = SHA1_DIGEST_LENGTH;
- } else {
- digest->cd_length = 0;
- }
-
- kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t));
- ctx->cc_provider_private = NULL;
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha1_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * Do the SHA1 update on the specified input data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA1Update(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_update_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_update_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha1_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((digest->cd_length == 0) ||
- (digest->cd_length < SHA1_DIGEST_LENGTH)) {
- digest->cd_length = SHA1_DIGEST_LENGTH;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do a SHA1 final.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA1Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &PROV_SHA1_CTX(ctx)->sc_sha1_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_final_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- digest, SHA1_DIGEST_LENGTH, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_final_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
- digest, SHA1_DIGEST_LENGTH, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- /* all done, free context and return */
-
- if (ret == CRYPTO_SUCCESS) {
- digest->cd_length = SHA1_DIGEST_LENGTH;
- } else {
- digest->cd_length = 0;
- }
-
- kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t));
- ctx->cc_provider_private = NULL;
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha1_digest_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_data_t *data, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- SHA1_CTX sha1_ctx;
-
- if (mechanism->cm_type != SHA1_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /*
- * Do the SHA1 init.
- */
- SHA1Init(&sha1_ctx);
-
- /*
- * Do the SHA1 update on the specified input data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA1Update(&sha1_ctx,
- (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_update_uio(&sha1_ctx, data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_update_mblk(&sha1_ctx, data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret != CRYPTO_SUCCESS) {
- /* the update failed, bail */
- digest->cd_length = 0;
- return (ret);
- }
-
- /*
- * Do a SHA1 final, must be done separately since the digest
- * type can be different than the input data type.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA1Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &sha1_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_final_uio(&sha1_ctx, digest,
- SHA1_DIGEST_LENGTH, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_final_mblk(&sha1_ctx, digest,
- SHA1_DIGEST_LENGTH, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS) {
- digest->cd_length = SHA1_DIGEST_LENGTH;
- } else {
- digest->cd_length = 0;
- }
-
- return (ret);
-}
-
-/*
- * KCF software provider mac entry points.
- *
- * SHA1 HMAC is: SHA1(key XOR opad, SHA1(key XOR ipad, text))
- *
- * Init:
- * The initialization routine initializes what we denote
- * as the inner and outer contexts by doing
- * - for inner context: SHA1(key XOR ipad)
- * - for outer context: SHA1(key XOR opad)
- *
- * Update:
- * Each subsequent SHA1 HMAC update will result in an
- * update of the inner context with the specified data.
- *
- * Final:
- * The SHA1 HMAC final will do a SHA1 final operation on the
- * inner context, and the resulting digest will be used
- * as the data for an update on the outer context. Last
- * but not least, a SHA1 final on the outer context will
- * be performed to obtain the SHA1 HMAC digest to return
- * to the user.
- */
-
-/*
- * Initialize a SHA1-HMAC context.
- */
-static void
-sha1_mac_init_ctx(sha1_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
-{
- uint32_t ipad[SHA1_HMAC_INTS_PER_BLOCK];
- uint32_t opad[SHA1_HMAC_INTS_PER_BLOCK];
- uint_t i;
-
- bzero(ipad, SHA1_HMAC_BLOCK_SIZE);
- bzero(opad, SHA1_HMAC_BLOCK_SIZE);
-
- bcopy(keyval, ipad, length_in_bytes);
- bcopy(keyval, opad, length_in_bytes);
-
- /* XOR key with ipad (0x36) and opad (0x5c) */
- for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
- ipad[i] ^= 0x36363636;
- opad[i] ^= 0x5c5c5c5c;
- }
-
- /* perform SHA1 on ipad */
- SHA1Init(&ctx->hc_icontext);
- SHA1Update(&ctx->hc_icontext, (uint8_t *)ipad, SHA1_HMAC_BLOCK_SIZE);
-
- /* perform SHA1 on opad */
- SHA1Init(&ctx->hc_ocontext);
- SHA1Update(&ctx->hc_ocontext, (uint8_t *)opad, SHA1_HMAC_BLOCK_SIZE);
-}
-
-/*
- */
-static int
-sha1_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE &&
- mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- ctx->cc_provider_private = kmem_alloc(sizeof (sha1_hmac_ctx_t),
- crypto_kmflag(req));
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, PROV_SHA1_HMAC_CTX(ctx),
- sizeof (sha1_hmac_ctx_t));
- } else {
- /* no context template, compute context */
- if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) {
- uchar_t digested_key[SHA1_DIGEST_LENGTH];
- sha1_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
-
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_SHA1_DIGEST_KEY(&hmac_ctx->hc_icontext,
- key->ck_data, keylen_in_bytes, digested_key);
- sha1_mac_init_ctx(PROV_SHA1_HMAC_CTX(ctx),
- digested_key, SHA1_DIGEST_LENGTH);
- } else {
- sha1_mac_init_ctx(PROV_SHA1_HMAC_CTX(ctx),
- key->ck_data, keylen_in_bytes);
- }
- }
-
- /*
- * Get the mechanism parameters, if applicable.
- */
- PROV_SHA1_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
- if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t))
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- PROV_SHA1_GET_DIGEST_LEN(mechanism,
- PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len);
- if (PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len >
- SHA1_DIGEST_LENGTH)
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- }
-
- if (ret != CRYPTO_SUCCESS) {
- bzero(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t));
- kmem_free(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t));
- ctx->cc_provider_private = NULL;
- }
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha1_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * Do a SHA1 update of the inner context using the specified
- * data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA1Update(&PROV_SHA1_HMAC_CTX(ctx)->hc_icontext,
- (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_update_uio(
- &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext, data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_update_mblk(
- &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext, data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha1_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[SHA1_DIGEST_LENGTH];
- uint32_t digest_len = SHA1_DIGEST_LENGTH;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- if (PROV_SHA1_HMAC_CTX(ctx)->hc_mech_type ==
- SHA1_HMAC_GEN_MECH_INFO_TYPE)
- digest_len = PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len;
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
- mac->cd_length = digest_len;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do a SHA1 final on the inner context.
- */
- SHA1Final(digest, &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext);
-
- /*
- * Do a SHA1 update on the outer context, feeding the inner
- * digest as data.
- */
- SHA1Update(&PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, digest,
- SHA1_DIGEST_LENGTH);
-
- /*
- * Do a SHA1 final on the outer context, storing the computing
- * digest in the users buffer.
- */
- switch (mac->cd_format) {
- case CRYPTO_DATA_RAW:
- if (digest_len != SHA1_DIGEST_LENGTH) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- SHA1Final(digest,
- &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext);
- bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len);
- } else {
- SHA1Final((unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset,
- &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext);
- }
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_final_uio(
- &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, mac,
- digest_len, digest);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_final_mblk(
- &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, mac,
- digest_len, digest);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS) {
- mac->cd_length = digest_len;
- } else {
- mac->cd_length = 0;
- }
-
- bzero(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t));
- kmem_free(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t));
- ctx->cc_provider_private = NULL;
-
- return (ret);
-}
-
-#define SHA1_MAC_UPDATE(data, ctx, ret) { \
- switch (data->cd_format) { \
- case CRYPTO_DATA_RAW: \
- SHA1Update(&(ctx).hc_icontext, \
- (uint8_t *)data->cd_raw.iov_base + \
- data->cd_offset, data->cd_length); \
- break; \
- case CRYPTO_DATA_UIO: \
- ret = sha1_digest_update_uio(&(ctx).hc_icontext, data); \
- break; \
- case CRYPTO_DATA_MBLK: \
- ret = sha1_digest_update_mblk(&(ctx).hc_icontext, \
- data); \
- break; \
- default: \
- ret = CRYPTO_ARGUMENTS_BAD; \
- } \
-}
-
-/* ARGSUSED */
-static int
-sha1_mac_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
- crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[SHA1_DIGEST_LENGTH];
- sha1_hmac_ctx_t sha1_hmac_ctx;
- uint32_t digest_len = SHA1_DIGEST_LENGTH;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE &&
- mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, &sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
- } else {
- /* no context template, initialize context */
- if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) {
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx.hc_icontext,
- key->ck_data, keylen_in_bytes, digest);
- sha1_mac_init_ctx(&sha1_hmac_ctx, digest,
- SHA1_DIGEST_LENGTH);
- } else {
- sha1_mac_init_ctx(&sha1_hmac_ctx, key->ck_data,
- keylen_in_bytes);
- }
- }
-
- /* get the mechanism parameters, if applicable */
- if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t)) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- PROV_SHA1_GET_DIGEST_LEN(mechanism, digest_len);
- if (digest_len > SHA1_DIGEST_LENGTH) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- }
-
- /* do a SHA1 update of the inner context using the specified data */
- SHA1_MAC_UPDATE(data, sha1_hmac_ctx, ret);
- if (ret != CRYPTO_SUCCESS)
- /* the update failed, free context and bail */
- goto bail;
-
- /*
- * Do a SHA1 final on the inner context.
- */
- SHA1Final(digest, &sha1_hmac_ctx.hc_icontext);
-
- /*
- * Do an SHA1 update on the outer context, feeding the inner
- * digest as data.
- */
- SHA1Update(&sha1_hmac_ctx.hc_ocontext, digest, SHA1_DIGEST_LENGTH);
-
- /*
- * Do a SHA1 final on the outer context, storing the computed
- * digest in the users buffer.
- */
- switch (mac->cd_format) {
- case CRYPTO_DATA_RAW:
- if (digest_len != SHA1_DIGEST_LENGTH) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- SHA1Final(digest, &sha1_hmac_ctx.hc_ocontext);
- bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len);
- } else {
- SHA1Final((unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, &sha1_hmac_ctx.hc_ocontext);
- }
- break;
- case CRYPTO_DATA_UIO:
- ret = sha1_digest_final_uio(&sha1_hmac_ctx.hc_ocontext, mac,
- digest_len, digest);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha1_digest_final_mblk(&sha1_hmac_ctx.hc_ocontext, mac,
- digest_len, digest);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS) {
- mac->cd_length = digest_len;
- } else {
- mac->cd_length = 0;
- }
- /* Extra paranoia: zeroize the context on the stack */
- bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
-
- return (ret);
-bail:
- bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
- mac->cd_length = 0;
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha1_mac_verify_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
- crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[SHA1_DIGEST_LENGTH];
- sha1_hmac_ctx_t sha1_hmac_ctx;
- uint32_t digest_len = SHA1_DIGEST_LENGTH;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE &&
- mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)
- return (CRYPTO_MECHANISM_INVALID);
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, &sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
- } else {
- /* no context template, initialize context */
- if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) {
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx.hc_icontext,
- key->ck_data, keylen_in_bytes, digest);
- sha1_mac_init_ctx(&sha1_hmac_ctx, digest,
- SHA1_DIGEST_LENGTH);
- } else {
- sha1_mac_init_ctx(&sha1_hmac_ctx, key->ck_data,
- keylen_in_bytes);
- }
- }
-
- /* get the mechanism parameters, if applicable */
- if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t)) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- PROV_SHA1_GET_DIGEST_LEN(mechanism, digest_len);
- if (digest_len > SHA1_DIGEST_LENGTH) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- }
-
- if (mac->cd_length != digest_len) {
- ret = CRYPTO_INVALID_MAC;
- goto bail;
- }
-
- /* do a SHA1 update of the inner context using the specified data */
- SHA1_MAC_UPDATE(data, sha1_hmac_ctx, ret);
- if (ret != CRYPTO_SUCCESS)
- /* the update failed, free context and bail */
- goto bail;
-
- /* do a SHA1 final on the inner context */
- SHA1Final(digest, &sha1_hmac_ctx.hc_icontext);
-
- /*
- * Do an SHA1 update on the outer context, feeding the inner
- * digest as data.
- */
- SHA1Update(&sha1_hmac_ctx.hc_ocontext, digest, SHA1_DIGEST_LENGTH);
-
- /*
- * Do a SHA1 final on the outer context, storing the computed
- * digest in the users buffer.
- */
- SHA1Final(digest, &sha1_hmac_ctx.hc_ocontext);
-
- /*
- * Compare the computed digest against the expected digest passed
- * as argument.
- */
-
- switch (mac->cd_format) {
-
- case CRYPTO_DATA_RAW:
- if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len) != 0)
- ret = CRYPTO_INVALID_MAC;
- break;
-
- case CRYPTO_DATA_UIO: {
- off_t offset = mac->cd_offset;
- uint_t vec_idx;
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- /* we support only kernel buffer */
- if (mac->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /* jump to the first iovec containing the expected digest */
- for (vec_idx = 0;
- offset >= mac->cd_uio->uio_iov[vec_idx].iov_len &&
- vec_idx < mac->cd_uio->uio_iovcnt;
- offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == mac->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is
- * larger than the total size of the buffers
- * it provided.
- */
- ret = CRYPTO_DATA_LEN_RANGE;
- break;
- }
-
- /* do the comparison of computed digest vs specified one */
- while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) {
- cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
-
- if (bcmp(digest + scratch_offset,
- mac->cd_uio->uio_iov[vec_idx].iov_base + offset,
- cur_len) != 0) {
- ret = CRYPTO_INVALID_MAC;
- break;
- }
-
- length -= cur_len;
- vec_idx++;
- scratch_offset += cur_len;
- offset = 0;
- }
- break;
- }
-
- case CRYPTO_DATA_MBLK: {
- off_t offset = mac->cd_offset;
- mblk_t *mp;
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- /* jump to the first mblk_t containing the expected digest */
- for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than
- * the total size of the buffers it provided.
- */
- ret = CRYPTO_DATA_LEN_RANGE;
- break;
- }
-
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- if (bcmp(digest + scratch_offset,
- mp->b_rptr + offset, cur_len) != 0) {
- ret = CRYPTO_INVALID_MAC;
- break;
- }
-
- length -= cur_len;
- mp = mp->b_cont;
- scratch_offset += cur_len;
- offset = 0;
- }
- break;
- }
-
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
- return (ret);
-bail:
- bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
- mac->cd_length = 0;
- return (ret);
-}
-
-/*
- * KCF software provider context management entry points.
- */
-
-/* ARGSUSED */
-static int
-sha1_create_ctx_template(crypto_provider_handle_t provider,
- crypto_mechanism_t *mechanism, crypto_key_t *key,
- crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
- crypto_req_handle_t req)
-{
- sha1_hmac_ctx_t *sha1_hmac_ctx_tmpl;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- if ((mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE) &&
- (mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)) {
- return (CRYPTO_MECHANISM_INVALID);
- }
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Allocate and initialize SHA1 context.
- */
- sha1_hmac_ctx_tmpl = kmem_alloc(sizeof (sha1_hmac_ctx_t),
- crypto_kmflag(req));
- if (sha1_hmac_ctx_tmpl == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) {
- uchar_t digested_key[SHA1_DIGEST_LENGTH];
-
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx_tmpl->hc_icontext,
- key->ck_data, keylen_in_bytes, digested_key);
- sha1_mac_init_ctx(sha1_hmac_ctx_tmpl, digested_key,
- SHA1_DIGEST_LENGTH);
- } else {
- sha1_mac_init_ctx(sha1_hmac_ctx_tmpl, key->ck_data,
- keylen_in_bytes);
- }
-
- sha1_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
- *ctx_template = (crypto_spi_ctx_template_t)sha1_hmac_ctx_tmpl;
- *ctx_template_size = sizeof (sha1_hmac_ctx_t);
-
-
- return (CRYPTO_SUCCESS);
-}
-
-static int
-sha1_free_context(crypto_ctx_t *ctx)
-{
- uint_t ctx_len;
- sha1_mech_type_t mech_type;
-
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_SUCCESS);
-
- /*
- * We have to free either SHA1 or SHA1-HMAC contexts, which
- * have different lengths.
- */
-
- mech_type = PROV_SHA1_CTX(ctx)->sc_mech_type;
- if (mech_type == SHA1_MECH_INFO_TYPE)
- ctx_len = sizeof (sha1_ctx_t);
- else {
- ASSERT(mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
- mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE);
- ctx_len = sizeof (sha1_hmac_ctx_t);
- }
-
- bzero(ctx->cc_provider_private, ctx_len);
- kmem_free(ctx->cc_provider_private, ctx_len);
- ctx->cc_provider_private = NULL;
-
- return (CRYPTO_SUCCESS);
-}
-
-#endif /* _KERNEL */
diff --git a/usr/src/common/crypto/sha2/sha2.c b/usr/src/common/crypto/sha2/sha2.c
index 39e0382092..264aaf2fdc 100644
--- a/usr/src/common/crypto/sha2/sha2.c
+++ b/usr/src/common/crypto/sha2/sha2.c
@@ -39,34 +39,30 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysmacros.h>
+#define _SHA2_IMPL
#include <sys/sha2.h>
#include <sys/sha2_consts.h>
-#ifdef _KERNEL
-
-#include <sys/modctl.h>
-#include <sys/cmn_err.h>
-#include <sys/crypto/common.h>
-#include <sys/crypto/spi.h>
-#include <sys/strsun.h>
-
-/*
- * The sha2 module is created with two modlinkages:
- * - a modlmisc that allows consumers to directly call the entry points
- * SHA2Init, SHA2Update, and SHA2Final.
- * - a modlcrypto that allows the module to register with the Kernel
- * Cryptographic Framework (KCF) as a software provider for the SHA2
- * mechanisms.
- */
-
-#else
+#ifndef _KERNEL
#include <strings.h>
#include <stdlib.h>
#include <errno.h>
+#pragma weak SHA256Update = SHA2Update
+#pragma weak SHA384Update = SHA2Update
+#pragma weak SHA512Update = SHA2Update
+
+#pragma weak SHA256Final = SHA2Final
+#pragma weak SHA384Final = SHA2Final
+#pragma weak SHA512Final = SHA2Final
+
#endif /* !_KERNEL */
+#ifdef _KERNEL
+#include <sys/cmn_err.h>
+#endif /* _KERNEL */
+
static void Encode(uint8_t *, uint32_t *, size_t);
static void Encode64(uint8_t *, uint64_t *, size_t);
static void SHA256Transform(SHA2_CTX *, const uint8_t *);
@@ -108,264 +104,6 @@ static uint8_t PADDING[128] = { 0x80, /* all zeros */ };
T2 = BIGSIGMA0(a) + Maj(a, b, c); \
h = T1 + T2
-#ifdef _KERNEL
-
-static struct modlmisc modlmisc = {
- &mod_miscops,
- "SHA2 Message-Digest Algorithm"
-};
-
-static struct modlcrypto modlcrypto = {
- &mod_cryptoops,
- "SHA2 Kernel SW Provider %I%"
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1, &modlmisc, &modlcrypto, NULL
-};
-
-/*
- * CSPI information (entry points, provider info, etc.)
- */
-
-#endif /* _KERNEL */
-
-/*
- * List of support mechanisms in this module.
- *
- * It is important to note that in the module, division or modulus calculations
- * are used on the enumerated type to determine which mechanism is being used;
- * therefore, changing the order or additional mechanisms should be done
- * carefully
- */
-typedef enum sha2_mech_type {
- SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */
- SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
- SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
- SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */
- SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */
- SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */
- SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */
- SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */
- SHA512_HMAC_GEN_MECH_INFO_TYPE /* SUN_CKM_SHA512_HMAC_GENERAL */
-} sha2_mech_type_t;
-
-#ifdef _KERNEL
-
-
-/*
- * Context for SHA2 mechanism.
- */
-typedef struct sha2_ctx {
- sha2_mech_type_t sc_mech_type; /* type of context */
- SHA2_CTX sc_sha2_ctx; /* SHA2 context */
-} sha2_ctx_t;
-
-/*
- * Context for SHA2 HMAC and HMAC GENERAL mechanisms.
- */
-typedef struct sha2_hmac_ctx {
- sha2_mech_type_t hc_mech_type; /* type of context */
- uint32_t hc_digest_len; /* digest len in bytes */
- SHA2_CTX hc_icontext; /* inner SHA2 context */
- SHA2_CTX hc_ocontext; /* outer SHA2 context */
-} sha2_hmac_ctx_t;
-
-/*
- * Macros to access the SHA2 or SHA2-HMAC contexts from a context passed
- * by KCF to one of the entry points.
- */
-
-#define PROV_SHA2_CTX(ctx) ((sha2_ctx_t *)(ctx)->cc_provider_private)
-#define PROV_SHA2_HMAC_CTX(ctx) ((sha2_hmac_ctx_t *)(ctx)->cc_provider_private)
-
-/* to extract the digest length passed as mechanism parameter */
-#define PROV_SHA2_GET_DIGEST_LEN(m, len) { \
- if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \
- (len) = (uint32_t)*((ulong_t *)(m)->cm_param); \
- else { \
- ulong_t tmp_ulong; \
- bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \
- (len) = (uint32_t)tmp_ulong; \
- } \
-}
-
-#define PROV_SHA2_DIGEST_KEY(mech, ctx, key, len, digest) { \
- SHA2Init(mech, ctx); \
- SHA2Update(ctx, key, len); \
- SHA2Final(digest, ctx); \
-}
-
-/*
- * Mechanism info structure passed to KCF during registration.
- */
-static crypto_mech_info_t sha2_mech_info_tab[] = {
- /* SHA256 */
- {SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
- CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
- 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA256-HMAC */
- {SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA256-HMAC GENERAL */
- {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA384 */
- {SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
- CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
- 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA384-HMAC */
- {SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA384-HMAC GENERAL */
- {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA512 */
- {SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
- CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
- 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA512-HMAC */
- {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS},
- /* SHA512-HMAC GENERAL */
- {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
- CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
- SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
- CRYPTO_KEYSIZE_UNIT_IN_BITS}
-};
-
-void SHA2Init(uint64_t, SHA2_CTX *);
-void SHA2Update(SHA2_CTX *, const uint8_t *, uint32_t);
-void SHA2Final(uint8_t *, SHA2_CTX *);
-
-static void sha2_provider_status(crypto_provider_handle_t, uint_t *);
-
-static crypto_control_ops_t sha2_control_ops = {
- sha2_provider_status
-};
-
-static int sha2_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
- crypto_req_handle_t);
-static int sha2_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int sha2_digest_update(crypto_ctx_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int sha2_digest_final(crypto_ctx_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int sha2_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
- crypto_req_handle_t);
-
-static crypto_digest_ops_t sha2_digest_ops = {
- sha2_digest_init,
- sha2_digest,
- sha2_digest_update,
- NULL,
- sha2_digest_final,
- sha2_digest_atomic
-};
-
-static int sha2_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int sha2_mac_update(crypto_ctx_t *, crypto_data_t *,
- crypto_req_handle_t);
-static int sha2_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
-static int sha2_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int sha2_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
- crypto_spi_ctx_template_t, crypto_req_handle_t);
-
-static crypto_mac_ops_t sha2_mac_ops = {
- sha2_mac_init,
- NULL,
- sha2_mac_update,
- sha2_mac_final,
- sha2_mac_atomic,
- sha2_mac_verify_atomic
-};
-
-static int sha2_create_ctx_template(crypto_provider_handle_t,
- crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
- size_t *, crypto_req_handle_t);
-static int sha2_free_context(crypto_ctx_t *);
-
-static crypto_ctx_ops_t sha2_ctx_ops = {
- sha2_create_ctx_template,
- sha2_free_context
-};
-
-static crypto_ops_t sha2_crypto_ops = {
- &sha2_control_ops,
- &sha2_digest_ops,
- NULL,
- &sha2_mac_ops,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- &sha2_ctx_ops
-};
-
-static crypto_provider_info_t sha2_prov_info = {
- CRYPTO_SPI_VERSION_1,
- "SHA2 Software Provider",
- CRYPTO_SW_PROVIDER,
- {&modlinkage},
- NULL,
- &sha2_crypto_ops,
- sizeof (sha2_mech_info_tab)/sizeof (crypto_mech_info_t),
- sha2_mech_info_tab
-};
-
-static crypto_kcf_provider_handle_t sha2_prov_handle = NULL;
-
-int
-_init()
-{
- int ret;
-
- if ((ret = mod_install(&modlinkage)) != 0)
- return (ret);
-
- /*
- * Register with KCF. If the registration fails, log an
- * error but do not uninstall the module, since the functionality
- * provided by misc/sha2 should still be available.
- */
- if ((ret = crypto_register_provider(&sha2_prov_info,
- &sha2_prov_handle)) != CRYPTO_SUCCESS)
- cmn_err(CE_WARN, "sha2 _init: "
- "crypto_register_provider() failed (0x%x)", ret);
-
- return (0);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-#endif /* _KERNEL */
-
-
/*
* sparc optimization:
*
@@ -452,93 +190,55 @@ SHA256Transform(SHA2_CTX *ctx, const uint8_t *blk)
blk = (uint8_t *)ctx->buf_un.buf32;
}
-#if defined(__sparc)
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w0 = LOAD_BIG_32(blk + 4 * 0);
SHA256ROUND(a, b, c, d, e, f, g, h, 0, w0);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w1 = LOAD_BIG_32(blk + 4 * 1);
SHA256ROUND(h, a, b, c, d, e, f, g, 1, w1);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w2 = LOAD_BIG_32(blk + 4 * 2);
SHA256ROUND(g, h, a, b, c, d, e, f, 2, w2);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w3 = LOAD_BIG_32(blk + 4 * 3);
SHA256ROUND(f, g, h, a, b, c, d, e, 3, w3);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w4 = LOAD_BIG_32(blk + 4 * 4);
SHA256ROUND(e, f, g, h, a, b, c, d, 4, w4);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w5 = LOAD_BIG_32(blk + 4 * 5);
SHA256ROUND(d, e, f, g, h, a, b, c, 5, w5);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w6 = LOAD_BIG_32(blk + 4 * 6);
SHA256ROUND(c, d, e, f, g, h, a, b, 6, w6);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w7 = LOAD_BIG_32(blk + 4 * 7);
SHA256ROUND(b, c, d, e, f, g, h, a, 7, w7);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w8 = LOAD_BIG_32(blk + 4 * 8);
SHA256ROUND(a, b, c, d, e, f, g, h, 8, w8);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w9 = LOAD_BIG_32(blk + 4 * 9);
SHA256ROUND(h, a, b, c, d, e, f, g, 9, w9);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w10 = LOAD_BIG_32(blk + 4 * 10);
SHA256ROUND(g, h, a, b, c, d, e, f, 10, w10);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w11 = LOAD_BIG_32(blk + 4 * 11);
SHA256ROUND(f, g, h, a, b, c, d, e, 11, w11);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w12 = LOAD_BIG_32(blk + 4 * 12);
SHA256ROUND(e, f, g, h, a, b, c, d, 12, w12);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w13 = LOAD_BIG_32(blk + 4 * 13);
SHA256ROUND(d, e, f, g, h, a, b, c, 13, w13);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w14 = LOAD_BIG_32(blk + 4 * 14);
SHA256ROUND(c, d, e, f, g, h, a, b, 14, w14);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w15 = LOAD_BIG_32(blk + 4 * 15);
SHA256ROUND(b, c, d, e, f, g, h, a, 15, w15);
-#else
-
- w0 = LOAD_BIG_32(blk + 4 * 0);
- SHA256ROUND(a, b, c, d, e, f, g, h, 0, w0);
- w1 = LOAD_BIG_32(blk + 4 * 1);
- SHA256ROUND(h, a, b, c, d, e, f, g, 1, w1);
- w2 = LOAD_BIG_32(blk + 4 * 2);
- SHA256ROUND(g, h, a, b, c, d, e, f, 2, w2);
- w3 = LOAD_BIG_32(blk + 4 * 3);
- SHA256ROUND(f, g, h, a, b, c, d, e, 3, w3);
- w4 = LOAD_BIG_32(blk + 4 * 4);
- SHA256ROUND(e, f, g, h, a, b, c, d, 4, w4);
- w5 = LOAD_BIG_32(blk + 4 * 5);
- SHA256ROUND(d, e, f, g, h, a, b, c, 5, w5);
- w6 = LOAD_BIG_32(blk + 4 * 6);
- SHA256ROUND(c, d, e, f, g, h, a, b, 6, w6);
- w7 = LOAD_BIG_32(blk + 4 * 7);
- SHA256ROUND(b, c, d, e, f, g, h, a, 7, w7);
- w8 = LOAD_BIG_32(blk + 4 * 8);
- SHA256ROUND(a, b, c, d, e, f, g, h, 8, w8);
- w9 = LOAD_BIG_32(blk + 4 * 9);
- SHA256ROUND(h, a, b, c, d, e, f, g, 9, w9);
- w10 = LOAD_BIG_32(blk + 4 * 10);
- SHA256ROUND(g, h, a, b, c, d, e, f, 10, w10);
- w11 = LOAD_BIG_32(blk + 4 * 11);
- SHA256ROUND(f, g, h, a, b, c, d, e, 11, w11);
- w12 = LOAD_BIG_32(blk + 4 * 12);
- SHA256ROUND(e, f, g, h, a, b, c, d, 12, w12);
- w13 = LOAD_BIG_32(blk + 4 * 13);
- SHA256ROUND(d, e, f, g, h, a, b, c, 13, w13);
- w14 = LOAD_BIG_32(blk + 4 * 14);
- SHA256ROUND(c, d, e, f, g, h, a, b, 14, w14);
- w15 = LOAD_BIG_32(blk + 4 * 15);
- SHA256ROUND(b, c, d, e, f, g, h, a, 15, w15);
-
-#endif
-
w0 = SIGMA1_256(w14) + w9 + SIGMA0_256(w1) + w0;
SHA256ROUND(a, b, c, d, e, f, g, h, 16, w0);
w1 = SIGMA1_256(w15) + w10 + SIGMA0_256(w2) + w1;
@@ -706,93 +406,55 @@ SHA512Transform(SHA2_CTX *ctx, const uint8_t *blk)
blk = (uint8_t *)ctx->buf_un.buf64;
}
-#if defined(__sparc)
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w0 = LOAD_BIG_64(blk + 8 * 0);
SHA512ROUND(a, b, c, d, e, f, g, h, 0, w0);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w1 = LOAD_BIG_64(blk + 8 * 1);
SHA512ROUND(h, a, b, c, d, e, f, g, 1, w1);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w2 = LOAD_BIG_64(blk + 8 * 2);
SHA512ROUND(g, h, a, b, c, d, e, f, 2, w2);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w3 = LOAD_BIG_64(blk + 8 * 3);
SHA512ROUND(f, g, h, a, b, c, d, e, 3, w3);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w4 = LOAD_BIG_64(blk + 8 * 4);
SHA512ROUND(e, f, g, h, a, b, c, d, 4, w4);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w5 = LOAD_BIG_64(blk + 8 * 5);
SHA512ROUND(d, e, f, g, h, a, b, c, 5, w5);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w6 = LOAD_BIG_64(blk + 8 * 6);
SHA512ROUND(c, d, e, f, g, h, a, b, 6, w6);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w7 = LOAD_BIG_64(blk + 8 * 7);
SHA512ROUND(b, c, d, e, f, g, h, a, 7, w7);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w8 = LOAD_BIG_64(blk + 8 * 8);
SHA512ROUND(a, b, c, d, e, f, g, h, 8, w8);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w9 = LOAD_BIG_64(blk + 8 * 9);
SHA512ROUND(h, a, b, c, d, e, f, g, 9, w9);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w10 = LOAD_BIG_64(blk + 8 * 10);
SHA512ROUND(g, h, a, b, c, d, e, f, 10, w10);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w11 = LOAD_BIG_64(blk + 8 * 11);
SHA512ROUND(f, g, h, a, b, c, d, e, 11, w11);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w12 = LOAD_BIG_64(blk + 8 * 12);
SHA512ROUND(e, f, g, h, a, b, c, d, 12, w12);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w13 = LOAD_BIG_64(blk + 8 * 13);
SHA512ROUND(d, e, f, g, h, a, b, c, 13, w13);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w14 = LOAD_BIG_64(blk + 8 * 14);
SHA512ROUND(c, d, e, f, g, h, a, b, 14, w14);
- /*LINTED*/
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
w15 = LOAD_BIG_64(blk + 8 * 15);
SHA512ROUND(b, c, d, e, f, g, h, a, 15, w15);
-#else
-
- w0 = LOAD_BIG_64(blk + 8 * 0);
- SHA512ROUND(a, b, c, d, e, f, g, h, 0, w0);
- w1 = LOAD_BIG_64(blk + 8 * 1);
- SHA512ROUND(h, a, b, c, d, e, f, g, 1, w1);
- w2 = LOAD_BIG_64(blk + 8 * 2);
- SHA512ROUND(g, h, a, b, c, d, e, f, 2, w2);
- w3 = LOAD_BIG_64(blk + 8 * 3);
- SHA512ROUND(f, g, h, a, b, c, d, e, 3, w3);
- w4 = LOAD_BIG_64(blk + 8 * 4);
- SHA512ROUND(e, f, g, h, a, b, c, d, 4, w4);
- w5 = LOAD_BIG_64(blk + 8 * 5);
- SHA512ROUND(d, e, f, g, h, a, b, c, 5, w5);
- w6 = LOAD_BIG_64(blk + 8 * 6);
- SHA512ROUND(c, d, e, f, g, h, a, b, 6, w6);
- w7 = LOAD_BIG_64(blk + 8 * 7);
- SHA512ROUND(b, c, d, e, f, g, h, a, 7, w7);
- w8 = LOAD_BIG_64(blk + 8 * 8);
- SHA512ROUND(a, b, c, d, e, f, g, h, 8, w8);
- w9 = LOAD_BIG_64(blk + 8 * 9);
- SHA512ROUND(h, a, b, c, d, e, f, g, 9, w9);
- w10 = LOAD_BIG_64(blk + 8 * 10);
- SHA512ROUND(g, h, a, b, c, d, e, f, 10, w10);
- w11 = LOAD_BIG_64(blk + 8 * 11);
- SHA512ROUND(f, g, h, a, b, c, d, e, 11, w11);
- w12 = LOAD_BIG_64(blk + 8 * 12);
- SHA512ROUND(e, f, g, h, a, b, c, d, 12, w12);
- w13 = LOAD_BIG_64(blk + 8 * 13);
- SHA512ROUND(d, e, f, g, h, a, b, c, 13, w13);
- w14 = LOAD_BIG_64(blk + 8 * 14);
- SHA512ROUND(c, d, e, f, g, h, a, b, 14, w14);
- w15 = LOAD_BIG_64(blk + 8 * 15);
- SHA512ROUND(b, c, d, e, f, g, h, a, 15, w15);
-
-#endif
-
w0 = SIGMA1(w14) + w9 + SIGMA0(w1) + w0;
SHA512ROUND(a, b, c, d, e, f, g, h, 16, w0);
w1 = SIGMA1(w15) + w10 + SIGMA0(w2) + w1;
@@ -938,21 +600,6 @@ SHA512Transform(SHA2_CTX *ctx, const uint8_t *blk)
/*
- * devpro compiler optimization:
- *
- * the compiler can generate better code if it knows that `input' and
- * `output' do not point to the same source. there is no portable
- * way to tell the compiler this, but the sun compiler recognizes the
- * `_Restrict' keyword to indicate this condition. use it if possible.
- */
-
-#ifdef __RESTRICT
-#define restrict _Restrict
-#else
-#define restrict /* nothing */
-#endif
-
-/*
* Encode()
*
* purpose: to convert a list of numbers from little endian to big endian
@@ -963,7 +610,8 @@ SHA512Transform(SHA2_CTX *ctx, const uint8_t *blk)
*/
static void
-Encode(uint8_t *restrict output, uint32_t *restrict input, size_t len)
+Encode(uint8_t *_RESTRICT_KYWD output, uint32_t *_RESTRICT_KYWD input,
+ size_t len)
{
size_t i, j;
@@ -987,7 +635,8 @@ Encode(uint8_t *restrict output, uint32_t *restrict input, size_t len)
}
static void
-Encode64(uint8_t *restrict output, uint64_t *restrict input, size_t len)
+Encode64(uint8_t *_RESTRICT_KYWD output, uint64_t *_RESTRICT_KYWD input,
+ size_t len)
{
size_t i, j;
@@ -1016,1358 +665,6 @@ Encode64(uint8_t *restrict output, uint64_t *restrict input, size_t len)
}
-#ifdef _KERNEL
-
-/*
- * KCF software provider control entry points.
- */
-/* ARGSUSED */
-static void
-sha2_provider_status(crypto_provider_handle_t provider, uint_t *status)
-{
- *status = CRYPTO_PROVIDER_READY;
-}
-
-/*
- * KCF software provider digest entry points.
- */
-
-static int
-sha2_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
- crypto_req_handle_t req)
-{
-
- /*
- * Allocate and initialize SHA2 context.
- */
- ctx->cc_provider_private = kmem_alloc(sizeof (sha2_ctx_t),
- crypto_kmflag(req));
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- PROV_SHA2_CTX(ctx)->sc_mech_type = mechanism->cm_type;
- SHA2Init(mechanism->cm_type, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper SHA2 digest update function for uio data.
- */
-static int
-sha2_digest_update_uio(SHA2_CTX *sha2_ctx, crypto_data_t *data)
-{
- off_t offset = data->cd_offset;
- size_t length = data->cd_length;
- uint_t vec_idx;
- size_t cur_len;
-
- /* we support only kernel buffer */
- if (data->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Jump to the first iovec containing data to be
- * digested.
- */
- for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt &&
- offset >= data->cd_uio->uio_iov[vec_idx].iov_len;
- offset -= data->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == data->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- /*
- * Now do the digesting on the iovecs.
- */
- while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) {
- cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
-
- SHA2Update(sha2_ctx, (uint8_t *)data->cd_uio->
- uio_iov[vec_idx].iov_base + offset, cur_len);
- length -= cur_len;
- vec_idx++;
- offset = 0;
- }
-
- if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) {
- /*
- * The end of the specified iovec's was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper SHA2 digest final function for uio data.
- * digest_len is the length of the desired digest. If digest_len
- * is smaller than the default SHA2 digest length, the caller
- * must pass a scratch buffer, digest_scratch, which must
- * be at least the algorithm's digest length bytes.
- */
-static int
-sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest,
- ulong_t digest_len, uchar_t *digest_scratch)
-{
- off_t offset = digest->cd_offset;
- uint_t vec_idx;
-
- /* we support only kernel buffer */
- if (digest->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Jump to the first iovec containing ptr to the digest to
- * be returned.
- */
- for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len &&
- vec_idx < digest->cd_uio->uio_iovcnt;
- offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == digest->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is
- * larger than the total size of the buffers
- * it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- if (offset + digest_len <=
- digest->cd_uio->uio_iov[vec_idx].iov_len) {
- /*
- * The computed SHA2 digest will fit in the current
- * iovec.
- */
- if (((sha2_ctx->algotype <= SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
- (digest_len != SHA256_DIGEST_LENGTH)) ||
- ((sha2_ctx->algotype > SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
- (digest_len != SHA512_DIGEST_LENGTH))) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- SHA2Final(digest_scratch, sha2_ctx);
-
- bcopy(digest_scratch, (uchar_t *)digest->
- cd_uio->uio_iov[vec_idx].iov_base + offset,
- digest_len);
- } else {
- SHA2Final((uchar_t *)digest->
- cd_uio->uio_iov[vec_idx].iov_base + offset,
- sha2_ctx);
-
- }
- } else {
- /*
- * The computed digest will be crossing one or more iovec's.
- * This is bad performance-wise but we need to support it.
- * Allocate a small scratch buffer on the stack and
- * copy it piece meal to the specified digest iovec's.
- */
- uchar_t digest_tmp[SHA512_DIGEST_LENGTH];
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- SHA2Final(digest_tmp, sha2_ctx);
-
- while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) {
- cur_len =
- MIN(digest->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
- bcopy(digest_tmp + scratch_offset,
- digest->cd_uio->uio_iov[vec_idx].iov_base + offset,
- cur_len);
-
- length -= cur_len;
- vec_idx++;
- scratch_offset += cur_len;
- offset = 0;
- }
-
- if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) {
- /*
- * The end of the specified iovec's was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it
- * provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper SHA2 digest update for mblk's.
- */
-static int
-sha2_digest_update_mblk(SHA2_CTX *sha2_ctx, crypto_data_t *data)
-{
- off_t offset = data->cd_offset;
- size_t length = data->cd_length;
- mblk_t *mp;
- size_t cur_len;
-
- /*
- * Jump to the first mblk_t containing data to be digested.
- */
- for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- /*
- * Now do the digesting on the mblk chain.
- */
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- SHA2Update(sha2_ctx, mp->b_rptr + offset, cur_len);
- length -= cur_len;
- offset = 0;
- mp = mp->b_cont;
- }
-
- if (mp == NULL && length > 0) {
- /*
- * The end of the mblk was reached but the length requested
- * could not be processed, i.e. The caller requested
- * to digest more data than it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/*
- * Helper SHA2 digest final for mblk's.
- * digest_len is the length of the desired digest. If digest_len
- * is smaller than the default SHA2 digest length, the caller
- * must pass a scratch buffer, digest_scratch, which must
- * be at least the algorithm's digest length bytes.
- */
-static int
-sha2_digest_final_mblk(SHA2_CTX *sha2_ctx, crypto_data_t *digest,
- ulong_t digest_len, uchar_t *digest_scratch)
-{
- off_t offset = digest->cd_offset;
- mblk_t *mp;
-
- /*
- * Jump to the first mblk_t that will be used to store the digest.
- */
- for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than the
- * total size of the buffers it provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
-
- if (offset + digest_len <= MBLKL(mp)) {
- /*
- * The computed SHA2 digest will fit in the current mblk.
- * Do the SHA2Final() in-place.
- */
- if (((sha2_ctx->algotype <= SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
- (digest_len != SHA256_DIGEST_LENGTH)) ||
- ((sha2_ctx->algotype > SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
- (digest_len != SHA512_DIGEST_LENGTH))) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- SHA2Final(digest_scratch, sha2_ctx);
- bcopy(digest_scratch, mp->b_rptr + offset, digest_len);
- } else {
- SHA2Final(mp->b_rptr + offset, sha2_ctx);
- }
- } else {
- /*
- * The computed digest will be crossing one or more mblk's.
- * This is bad performance-wise but we need to support it.
- * Allocate a small scratch buffer on the stack and
- * copy it piece meal to the specified digest iovec's.
- */
- uchar_t digest_tmp[SHA512_DIGEST_LENGTH];
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- SHA2Final(digest_tmp, sha2_ctx);
-
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- bcopy(digest_tmp + scratch_offset,
- mp->b_rptr + offset, cur_len);
-
- length -= cur_len;
- mp = mp->b_cont;
- scratch_offset += cur_len;
- offset = 0;
- }
-
- if (mp == NULL && length > 0) {
- /*
- * The end of the specified mblk was reached but
- * the length requested could not be processed, i.e.
- * The caller requested to digest more data than it
- * provided.
- */
- return (CRYPTO_DATA_LEN_RANGE);
- }
- }
-
- return (CRYPTO_SUCCESS);
-}
-
-/* ARGSUSED */
-static int
-sha2_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uint_t sha_digest_len;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
- case SHA256_MECH_INFO_TYPE:
- sha_digest_len = SHA256_DIGEST_LENGTH;
- break;
- case SHA384_MECH_INFO_TYPE:
- sha_digest_len = SHA384_DIGEST_LENGTH;
- break;
- case SHA512_MECH_INFO_TYPE:
- sha_digest_len = SHA512_DIGEST_LENGTH;
- break;
- default:
- return (CRYPTO_MECHANISM_INVALID);
- }
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((digest->cd_length == 0) ||
- (digest->cd_length < sha_digest_len)) {
- digest->cd_length = sha_digest_len;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do the SHA2 update on the specified input data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_update_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret != CRYPTO_SUCCESS) {
- /* the update failed, free context and bail */
- kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
- ctx->cc_provider_private = NULL;
- digest->cd_length = 0;
- return (ret);
- }
-
- /*
- * Do a SHA2 final, must be done separately since the digest
- * type can be different than the input data type.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA2Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- digest, sha_digest_len, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_final_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- digest, sha_digest_len, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- /* all done, free context and return */
-
- if (ret == CRYPTO_SUCCESS)
- digest->cd_length = sha_digest_len;
- else
- digest->cd_length = 0;
-
- kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
- ctx->cc_provider_private = NULL;
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha2_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * Do the SHA2 update on the specified input data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_update_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha2_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uint_t sha_digest_len;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
- case SHA256_MECH_INFO_TYPE:
- sha_digest_len = SHA256_DIGEST_LENGTH;
- break;
- case SHA384_MECH_INFO_TYPE:
- sha_digest_len = SHA384_DIGEST_LENGTH;
- break;
- case SHA512_MECH_INFO_TYPE:
- sha_digest_len = SHA512_DIGEST_LENGTH;
- break;
- default:
- return (CRYPTO_MECHANISM_INVALID);
- }
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((digest->cd_length == 0) ||
- (digest->cd_length < sha_digest_len)) {
- digest->cd_length = sha_digest_len;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do a SHA2 final.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA2Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- digest, sha_digest_len, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_final_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
- digest, sha_digest_len, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- /* all done, free context and return */
-
- if (ret == CRYPTO_SUCCESS)
- digest->cd_length = sha_digest_len;
- else
- digest->cd_length = 0;
-
- kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
- ctx->cc_provider_private = NULL;
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha2_digest_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_data_t *data, crypto_data_t *digest,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- SHA2_CTX sha2_ctx;
- uint32_t sha_digest_len;
-
- /*
- * Do the SHA inits.
- */
-
- SHA2Init(mechanism->cm_type, &sha2_ctx);
-
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA2Update(&sha2_ctx, (uint8_t *)data->
- cd_raw.iov_base + data->cd_offset, data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_update_uio(&sha2_ctx, data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_update_mblk(&sha2_ctx, data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- /*
- * Do the SHA updates on the specified input data.
- */
-
- if (ret != CRYPTO_SUCCESS) {
- /* the update failed, bail */
- digest->cd_length = 0;
- return (ret);
- }
-
- if (mechanism->cm_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE)
- sha_digest_len = SHA256_DIGEST_LENGTH;
- else
- sha_digest_len = SHA512_DIGEST_LENGTH;
-
- /*
- * Do a SHA2 final, must be done separately since the digest
- * type can be different than the input data type.
- */
- switch (digest->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA2Final((unsigned char *)digest->cd_raw.iov_base +
- digest->cd_offset, &sha2_ctx);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_final_uio(&sha2_ctx, digest,
- sha_digest_len, NULL);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_final_mblk(&sha2_ctx, digest,
- sha_digest_len, NULL);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS)
- digest->cd_length = sha_digest_len;
- else
- digest->cd_length = 0;
-
- return (ret);
-}
-
-/*
- * KCF software provider mac entry points.
- *
- * SHA2 HMAC is: SHA2(key XOR opad, SHA2(key XOR ipad, text))
- *
- * Init:
- * The initialization routine initializes what we denote
- * as the inner and outer contexts by doing
- * - for inner context: SHA2(key XOR ipad)
- * - for outer context: SHA2(key XOR opad)
- *
- * Update:
- * Each subsequent SHA2 HMAC update will result in an
- * update of the inner context with the specified data.
- *
- * Final:
- * The SHA2 HMAC final will do a SHA2 final operation on the
- * inner context, and the resulting digest will be used
- * as the data for an update on the outer context. Last
- * but not least, a SHA2 final on the outer context will
- * be performed to obtain the SHA2 HMAC digest to return
- * to the user.
- */
-
-/*
- * Initialize a SHA2-HMAC context.
- */
-static void
-sha2_mac_init_ctx(sha2_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
-{
- uint64_t ipad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
- uint64_t opad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
- int i, block_size, blocks_per_int64;
-
- /* Determine the block size */
- if (ctx->hc_mech_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) {
- block_size = SHA256_HMAC_BLOCK_SIZE;
- blocks_per_int64 = SHA256_HMAC_BLOCK_SIZE / sizeof (uint64_t);
- } else {
- block_size = SHA512_HMAC_BLOCK_SIZE;
- blocks_per_int64 = SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t);
- }
-
- (void) bzero(ipad, block_size);
- (void) bzero(opad, block_size);
- (void) bcopy(keyval, ipad, length_in_bytes);
- (void) bcopy(keyval, opad, length_in_bytes);
-
- /* XOR key with ipad (0x36) and opad (0x5c) */
- for (i = 0; i < blocks_per_int64; i ++) {
- ipad[i] ^= 0x3636363636363636;
- opad[i] ^= 0x5c5c5c5c5c5c5c5c;
- }
-
- /* perform SHA2 on ipad */
- SHA2Init(ctx->hc_mech_type, &ctx->hc_icontext);
- SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
-
- /* perform SHA2 on opad */
- SHA2Init(ctx->hc_mech_type, &ctx->hc_ocontext);
- SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
-
-}
-
-/*
- */
-static int
-sha2_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
- uint_t sha_digest_len, sha_hmac_block_size;
-
- /*
- * Set the digest length and block size to values approriate to the
- * mechanism
- */
- switch (mechanism->cm_type) {
- case SHA256_HMAC_MECH_INFO_TYPE:
- case SHA256_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = SHA256_DIGEST_LENGTH;
- sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
- break;
- case SHA384_HMAC_MECH_INFO_TYPE:
- case SHA384_HMAC_GEN_MECH_INFO_TYPE:
- case SHA512_HMAC_MECH_INFO_TYPE:
- case SHA512_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = SHA512_DIGEST_LENGTH;
- sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
- break;
- default:
- return (CRYPTO_MECHANISM_INVALID);
- }
-
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- ctx->cc_provider_private = kmem_alloc(sizeof (sha2_hmac_ctx_t),
- crypto_kmflag(req));
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, PROV_SHA2_HMAC_CTX(ctx),
- sizeof (sha2_hmac_ctx_t));
- } else {
- /* no context template, compute context */
- if (keylen_in_bytes > sha_hmac_block_size) {
- uchar_t digested_key[SHA512_DIGEST_LENGTH];
- sha2_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
-
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
- &hmac_ctx->hc_icontext,
- key->ck_data, keylen_in_bytes, digested_key);
- sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx),
- digested_key, sha_digest_len);
- } else {
- sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx),
- key->ck_data, keylen_in_bytes);
- }
- }
-
- /*
- * Get the mechanism parameters, if applicable.
- */
- PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
- if (mechanism->cm_type % 3 == 2) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t))
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- PROV_SHA2_GET_DIGEST_LEN(mechanism,
- PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len);
- if (PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len > sha_digest_len)
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- }
-
- if (ret != CRYPTO_SUCCESS) {
- bzero(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
- kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
- ctx->cc_provider_private = NULL;
- }
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha2_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
- crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /*
- * Do a SHA2 update of the inner context using the specified
- * data.
- */
- switch (data->cd_format) {
- case CRYPTO_DATA_RAW:
- SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_icontext,
- (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
- data->cd_length);
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_update_uio(
- &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, data);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_update_mblk(
- &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, data);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha2_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[SHA512_DIGEST_LENGTH];
- uint32_t digest_len, sha_digest_len;
-
- ASSERT(ctx->cc_provider_private != NULL);
-
- /* Set the digest lengths to values approriate to the mechanism */
- switch (PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type) {
- case SHA256_HMAC_MECH_INFO_TYPE:
- sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
- break;
- case SHA384_HMAC_MECH_INFO_TYPE:
- case SHA512_HMAC_MECH_INFO_TYPE:
- sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
- break;
- case SHA256_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = SHA256_DIGEST_LENGTH;
- digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len;
- break;
- case SHA384_HMAC_GEN_MECH_INFO_TYPE:
- case SHA512_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = SHA512_DIGEST_LENGTH;
- digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len;
- break;
- }
-
- /*
- * We need to just return the length needed to store the output.
- * We should not destroy the context for the following cases.
- */
- if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
- mac->cd_length = digest_len;
- return (CRYPTO_BUFFER_TOO_SMALL);
- }
-
- /*
- * Do a SHA2 final on the inner context.
- */
- SHA2Final(digest, &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext);
-
- /*
- * Do a SHA2 update on the outer context, feeding the inner
- * digest as data.
- */
- SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, digest,
- sha_digest_len);
-
- /*
- * Do a SHA2 final on the outer context, storing the computing
- * digest in the users buffer.
- */
- switch (mac->cd_format) {
- case CRYPTO_DATA_RAW:
- if (digest_len != sha_digest_len) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- SHA2Final(digest,
- &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext);
- bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len);
- } else {
- SHA2Final((unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset,
- &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext);
- }
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_final_uio(
- &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, mac,
- digest_len, digest);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_final_mblk(
- &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, mac,
- digest_len, digest);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS)
- mac->cd_length = digest_len;
- else
- mac->cd_length = 0;
-
- bzero(&PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, sizeof (sha2_hmac_ctx_t));
- kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
- ctx->cc_provider_private = NULL;
-
- return (ret);
-}
-
-#define SHA2_MAC_UPDATE(data, ctx, ret) { \
- switch (data->cd_format) { \
- case CRYPTO_DATA_RAW: \
- SHA2Update(&(ctx).hc_icontext, \
- (uint8_t *)data->cd_raw.iov_base + \
- data->cd_offset, data->cd_length); \
- break; \
- case CRYPTO_DATA_UIO: \
- ret = sha2_digest_update_uio(&(ctx).hc_icontext, data); \
- break; \
- case CRYPTO_DATA_MBLK: \
- ret = sha2_digest_update_mblk(&(ctx).hc_icontext, \
- data); \
- break; \
- default: \
- ret = CRYPTO_ARGUMENTS_BAD; \
- } \
-}
-
-/* ARGSUSED */
-static int
-sha2_mac_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
- crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[SHA512_DIGEST_LENGTH];
- sha2_hmac_ctx_t sha2_hmac_ctx;
- uint32_t sha_digest_len, digest_len, sha_hmac_block_size;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- /*
- * Set the digest length and block size to values approriate to the
- * mechanism
- */
- switch (mechanism->cm_type) {
- case SHA256_HMAC_MECH_INFO_TYPE:
- case SHA256_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
- sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
- break;
- case SHA384_HMAC_MECH_INFO_TYPE:
- case SHA384_HMAC_GEN_MECH_INFO_TYPE:
- case SHA512_HMAC_MECH_INFO_TYPE:
- case SHA512_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
- sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
- break;
- default:
- return (CRYPTO_MECHANISM_INVALID);
- }
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, &sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
- } else {
- sha2_hmac_ctx.hc_mech_type = mechanism->cm_type;
- /* no context template, initialize context */
- if (keylen_in_bytes > sha_hmac_block_size) {
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
- &sha2_hmac_ctx.hc_icontext,
- key->ck_data, keylen_in_bytes, digest);
- sha2_mac_init_ctx(&sha2_hmac_ctx, digest,
- sha_digest_len);
- } else {
- sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data,
- keylen_in_bytes);
- }
- }
-
- /* get the mechanism parameters, if applicable */
- if ((mechanism->cm_type % 3) == 2) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t)) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- PROV_SHA2_GET_DIGEST_LEN(mechanism, digest_len);
- if (digest_len > sha_digest_len) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- }
-
- /* do a SHA2 update of the inner context using the specified data */
- SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret);
- if (ret != CRYPTO_SUCCESS)
- /* the update failed, free context and bail */
- goto bail;
-
- /*
- * Do a SHA2 final on the inner context.
- */
- SHA2Final(digest, &sha2_hmac_ctx.hc_icontext);
-
- /*
- * Do an SHA2 update on the outer context, feeding the inner
- * digest as data.
- *
- * Make sure that SHA384 is handled special because
- * it cannot feed a 60-byte inner hash to the outer
- */
- if (mechanism->cm_type == SHA384_HMAC_MECH_INFO_TYPE ||
- mechanism->cm_type == SHA384_HMAC_GEN_MECH_INFO_TYPE)
- SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest,
- SHA384_DIGEST_LENGTH);
- else
- SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len);
-
- /*
- * Do a SHA2 final on the outer context, storing the computed
- * digest in the users buffer.
- */
- switch (mac->cd_format) {
- case CRYPTO_DATA_RAW:
- if (digest_len != sha_digest_len) {
- /*
- * The caller requested a short digest. Digest
- * into a scratch buffer and return to
- * the user only what was requested.
- */
- SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext);
- bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len);
- } else {
- SHA2Final((unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, &sha2_hmac_ctx.hc_ocontext);
- }
- break;
- case CRYPTO_DATA_UIO:
- ret = sha2_digest_final_uio(&sha2_hmac_ctx.hc_ocontext, mac,
- digest_len, digest);
- break;
- case CRYPTO_DATA_MBLK:
- ret = sha2_digest_final_mblk(&sha2_hmac_ctx.hc_ocontext, mac,
- digest_len, digest);
- break;
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- if (ret == CRYPTO_SUCCESS) {
- mac->cd_length = digest_len;
- return (CRYPTO_SUCCESS);
- }
-bail:
- bzero(&sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
- mac->cd_length = 0;
- return (ret);
-}
-
-/* ARGSUSED */
-static int
-sha2_mac_verify_atomic(crypto_provider_handle_t provider,
- crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
- crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
- crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
-{
- int ret = CRYPTO_SUCCESS;
- uchar_t digest[SHA512_DIGEST_LENGTH];
- sha2_hmac_ctx_t sha2_hmac_ctx;
- uint32_t sha_digest_len, digest_len, sha_hmac_block_size;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
-
- /*
- * Set the digest length and block size to values approriate to the
- * mechanism
- */
- switch (mechanism->cm_type) {
- case SHA256_HMAC_MECH_INFO_TYPE:
- case SHA256_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
- sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
- break;
- case SHA384_HMAC_MECH_INFO_TYPE:
- case SHA384_HMAC_GEN_MECH_INFO_TYPE:
- case SHA512_HMAC_MECH_INFO_TYPE:
- case SHA512_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
- sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
- break;
- default:
- return (CRYPTO_MECHANISM_INVALID);
- }
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- if (ctx_template != NULL) {
- /* reuse context template */
- bcopy(ctx_template, &sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
- } else {
- /* no context template, initialize context */
- if (keylen_in_bytes > sha_hmac_block_size) {
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
- &sha2_hmac_ctx.hc_icontext,
- key->ck_data, keylen_in_bytes, digest);
- sha2_mac_init_ctx(&sha2_hmac_ctx, digest,
- sha_digest_len);
- } else {
- sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data,
- keylen_in_bytes);
- }
- }
-
- /* get the mechanism parameters, if applicable */
- if (mechanism->cm_type % 3 == 2) {
- if (mechanism->cm_param == NULL ||
- mechanism->cm_param_len != sizeof (ulong_t)) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- PROV_SHA2_GET_DIGEST_LEN(mechanism, digest_len);
- if (digest_len > sha_digest_len) {
- ret = CRYPTO_MECHANISM_PARAM_INVALID;
- goto bail;
- }
- }
-
- if (mac->cd_length != digest_len) {
- ret = CRYPTO_INVALID_MAC;
- goto bail;
- }
-
- /* do a SHA2 update of the inner context using the specified data */
- SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret);
- if (ret != CRYPTO_SUCCESS)
- /* the update failed, free context and bail */
- goto bail;
-
- /* do a SHA2 final on the inner context */
- SHA2Final(digest, &sha2_hmac_ctx.hc_icontext);
-
- /*
- * Do an SHA2 update on the outer context, feeding the inner
- * digest as data.
- */
- SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len);
-
- /*
- * Do a SHA2 final on the outer context, storing the computed
- * digest in the users buffer.
- */
- SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext);
-
- /*
- * Compare the computed digest against the expected digest passed
- * as argument.
- */
-
- switch (mac->cd_format) {
-
- case CRYPTO_DATA_RAW:
- if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
- mac->cd_offset, digest_len) != 0)
- ret = CRYPTO_INVALID_MAC;
- break;
-
- case CRYPTO_DATA_UIO: {
- off_t offset = mac->cd_offset;
- uint_t vec_idx;
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- /* we support only kernel buffer */
- if (mac->cd_uio->uio_segflg != UIO_SYSSPACE)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /* jump to the first iovec containing the expected digest */
- for (vec_idx = 0;
- offset >= mac->cd_uio->uio_iov[vec_idx].iov_len &&
- vec_idx < mac->cd_uio->uio_iovcnt;
- offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len);
- if (vec_idx == mac->cd_uio->uio_iovcnt) {
- /*
- * The caller specified an offset that is
- * larger than the total size of the buffers
- * it provided.
- */
- ret = CRYPTO_DATA_LEN_RANGE;
- break;
- }
-
- /* do the comparison of computed digest vs specified one */
- while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) {
- cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len -
- offset, length);
-
- if (bcmp(digest + scratch_offset,
- mac->cd_uio->uio_iov[vec_idx].iov_base + offset,
- cur_len) != 0) {
- ret = CRYPTO_INVALID_MAC;
- break;
- }
-
- length -= cur_len;
- vec_idx++;
- scratch_offset += cur_len;
- offset = 0;
- }
- break;
- }
-
- case CRYPTO_DATA_MBLK: {
- off_t offset = mac->cd_offset;
- mblk_t *mp;
- off_t scratch_offset = 0;
- size_t length = digest_len;
- size_t cur_len;
-
- /* jump to the first mblk_t containing the expected digest */
- for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp);
- offset -= MBLKL(mp), mp = mp->b_cont);
- if (mp == NULL) {
- /*
- * The caller specified an offset that is larger than
- * the total size of the buffers it provided.
- */
- ret = CRYPTO_DATA_LEN_RANGE;
- break;
- }
-
- while (mp != NULL && length > 0) {
- cur_len = MIN(MBLKL(mp) - offset, length);
- if (bcmp(digest + scratch_offset,
- mp->b_rptr + offset, cur_len) != 0) {
- ret = CRYPTO_INVALID_MAC;
- break;
- }
-
- length -= cur_len;
- mp = mp->b_cont;
- scratch_offset += cur_len;
- offset = 0;
- }
- break;
- }
-
- default:
- ret = CRYPTO_ARGUMENTS_BAD;
- }
-
- return (ret);
-bail:
- bzero(&sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
- mac->cd_length = 0;
- return (ret);
-}
-
-/*
- * KCF software provider context management entry points.
- */
-
-/* ARGSUSED */
-static int
-sha2_create_ctx_template(crypto_provider_handle_t provider,
- crypto_mechanism_t *mechanism, crypto_key_t *key,
- crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
- crypto_req_handle_t req)
-{
- sha2_hmac_ctx_t *sha2_hmac_ctx_tmpl;
- uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
- uint32_t sha_digest_len, sha_hmac_block_size;
-
- /*
- * Set the digest length and block size to values approriate to the
- * mechanism
- */
- switch (mechanism->cm_type) {
- case SHA256_HMAC_MECH_INFO_TYPE:
- case SHA256_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = SHA256_DIGEST_LENGTH;
- sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
- break;
- case SHA384_HMAC_MECH_INFO_TYPE:
- case SHA384_HMAC_GEN_MECH_INFO_TYPE:
- case SHA512_HMAC_MECH_INFO_TYPE:
- case SHA512_HMAC_GEN_MECH_INFO_TYPE:
- sha_digest_len = SHA512_DIGEST_LENGTH;
- sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
- break;
- default:
- return (CRYPTO_MECHANISM_INVALID);
- }
-
- /* Add support for key by attributes (RFE 4706552) */
- if (key->ck_format != CRYPTO_KEY_RAW)
- return (CRYPTO_ARGUMENTS_BAD);
-
- /*
- * Allocate and initialize SHA2 context.
- */
- sha2_hmac_ctx_tmpl = kmem_alloc(sizeof (sha2_hmac_ctx_t),
- crypto_kmflag(req));
- if (sha2_hmac_ctx_tmpl == NULL)
- return (CRYPTO_HOST_MEMORY);
-
- sha2_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
-
- if (keylen_in_bytes > sha_hmac_block_size) {
- uchar_t digested_key[SHA512_DIGEST_LENGTH];
-
- /*
- * Hash the passed-in key to get a smaller key.
- * The inner context is used since it hasn't been
- * initialized yet.
- */
- PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
- &sha2_hmac_ctx_tmpl->hc_icontext,
- key->ck_data, keylen_in_bytes, digested_key);
- sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, digested_key,
- sha_digest_len);
- } else {
- sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, key->ck_data,
- keylen_in_bytes);
- }
-
- *ctx_template = (crypto_spi_ctx_template_t)sha2_hmac_ctx_tmpl;
- *ctx_template_size = sizeof (sha2_hmac_ctx_t);
-
- return (CRYPTO_SUCCESS);
-}
-
-static int
-sha2_free_context(crypto_ctx_t *ctx)
-{
- uint_t ctx_len;
-
- if (ctx->cc_provider_private == NULL)
- return (CRYPTO_SUCCESS);
-
- /*
- * We have to free either SHA2 or SHA2-HMAC contexts, which
- * have different lengths.
- *
- * Note: Below is dependent on the mechanism ordering.
- */
-
- if (PROV_SHA2_CTX(ctx)->sc_mech_type % 3 == 0)
- ctx_len = sizeof (sha2_ctx_t);
- else
- ctx_len = sizeof (sha2_hmac_ctx_t);
-
- bzero(ctx->cc_provider_private, ctx_len);
- kmem_free(ctx->cc_provider_private, ctx_len);
- ctx->cc_provider_private = NULL;
-
- return (CRYPTO_SUCCESS);
-}
-
-#endif /* _KERNEL */
-
void
SHA2Init(uint64_t mech, SHA2_CTX *ctx)
{
@@ -2411,7 +708,7 @@ SHA2Init(uint64_t mech, SHA2_CTX *ctx)
break;
#ifdef _KERNEL
default:
- cmn_err(CE_WARN, "sha2_init: "
+ cmn_err(CE_PANIC, "sha2_init: "
"failed to find a supported algorithm: 0x%x",
(uint32_t)mech);
@@ -2422,21 +719,45 @@ SHA2Init(uint64_t mech, SHA2_CTX *ctx)
ctx->count.c64[0] = ctx->count.c64[1] = 0;
}
+#ifndef _KERNEL
+
+#pragma inline(SHA256Init, SHA384Init, SHA512Init)
+void
+SHA256Init(SHA256_CTX *ctx)
+{
+ SHA2Init(SHA256, ctx);
+}
+
+void
+SHA384Init(SHA384_CTX *ctx)
+{
+ SHA2Init(SHA384, ctx);
+}
+
+void
+SHA512Init(SHA512_CTX *ctx)
+{
+ SHA2Init(SHA512, ctx);
+}
+
+#endif /* _KERNEL */
+
/*
* SHA2Update()
*
* purpose: continues an sha2 digest operation, using the message block
* to update the context.
* input: SHA2_CTX * : the context to update
- * uint8_t * : the message block
- * uint32_t : the length of the message block in bytes
+ * void * : the message block
+ * size_t : the length of the message block in bytes
* output: void
*/
void
-SHA2Update(SHA2_CTX *ctx, const uint8_t *input, uint32_t input_len)
+SHA2Update(SHA2_CTX *ctx, const void *inptr, size_t input_len)
{
uint32_t i, buf_index, buf_len, buf_limit;
+ const uint8_t *input = inptr;
/* check for noop */
if (input_len == 0)
@@ -2529,9 +850,8 @@ SHA2Update(SHA2_CTX *ctx, const uint8_t *input, uint32_t input_len)
* output: void
*/
-
void
-SHA2Final(uint8_t *digest, SHA2_CTX *ctx)
+SHA2Final(void *digest, SHA2_CTX *ctx)
{
uint8_t bitcount_be[sizeof (ctx->count.c32)];
uint8_t bitcount_be64[sizeof (ctx->count.c64)];
diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile
index 4c1ae87327..2c7ee4ce4e 100644
--- a/usr/src/head/Makefile
+++ b/usr/src/head/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -97,7 +96,6 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) \
locale.h \
macros.h \
malloc.h \
- md5.h \
mdmn_changelog.h \
memory.h \
meta.h \
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index c7d90d71de..cfcba443d5 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -65,6 +65,7 @@ SUBDIRS += \
libc .WAIT \
libmapmalloc .WAIT \
../cmd/sgs/libelf .WAIT \
+ libmd \
libmd5 \
librsm \
libmp .WAIT \
@@ -217,8 +218,7 @@ SUBDIRS += \
sparc_SUBDIRS= .WAIT \
efcode \
- libc_psr .WAIT \
- libmd5_psr .WAIT
+ libc_psr .WAIT
$(CLOSED_BUILD)sparc_SUBDIRS += \
$(CLOSED)/lib/libprtdiag .WAIT \
$(CLOSED)/lib/libprtdiag_psr \
@@ -328,6 +328,7 @@ HDRSUBDIRS= libaio \
liblaadm \
libmacadm \
libmail \
+ libmd \
libmtmalloc \
libnvpair \
libnsl \
@@ -451,12 +452,12 @@ libmacadm: libdevinfo
libuuid: libsocket
libinetutil: libsocket
libsecdb: libcmd libnsl
-librt: libaio libmd5
-libsasl: libgss libsocket pkcs11 libmd5
+librt: libaio libmd
+libsasl: libgss libsocket pkcs11 libmd
sasl_plugins: pkcs11 libgss libsocket libsasl
libsctp: libsocket
libsocket: libnsl
-libldap5: libsasl libsocket libnsl libmd5
+libldap5: libsasl libsocket libnsl libmd
libsldap: libldap5 libtsol
libpool: libnvpair libexacct
libproject: libpool libproc libsecdb
@@ -466,7 +467,7 @@ libwanboot: libnvpair libresolv libnsl libsocket libdevinfo libinetutil \
libdhcputil openssl
libwanbootutil: libnsl
pam_modules: libproject passwdutil $(SMARTCARD)
-libscf: libuutil
+libscf: libuutil libmd
libinetsvc: libscf
librestart: libuutil libscf
../cmd/sgs/libdl: ../cmd/sgs/libconv
diff --git a/usr/src/lib/crypt_modules/bsdmd5/Makefile.com b/usr/src/lib/crypt_modules/bsdmd5/Makefile.com
index f2e6fa9136..c9e7fa3ad6 100644
--- a/usr/src/lib/crypt_modules/bsdmd5/Makefile.com
+++ b/usr/src/lib/crypt_modules/bsdmd5/Makefile.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -31,7 +30,7 @@ OBJECTS= bsdmd5.o
include ../../Makefile.crypt_modules
-LDLIBS += -lc -lmd5
+LDLIBS += -lc -lmd
all: $(LIBS)
diff --git a/usr/src/lib/crypt_modules/sunmd5/Makefile.com b/usr/src/lib/crypt_modules/sunmd5/Makefile.com
index f9f335896e..6982c0ce63 100644
--- a/usr/src/lib/crypt_modules/sunmd5/Makefile.com
+++ b/usr/src/lib/crypt_modules/sunmd5/Makefile.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -31,7 +30,7 @@ OBJECTS= sunmd5.o
include ../../Makefile.crypt_modules
-LDLIBS += -lc -lmd5
+LDLIBS += -lc -lmd
all: $(LIBS)
diff --git a/usr/src/lib/libbsm/Makefile.com b/usr/src/lib/libbsm/Makefile.com
index 52871561fc..399ed7a3dd 100644
--- a/usr/src/lib/libbsm/Makefile.com
+++ b/usr/src/lib/libbsm/Makefile.com
@@ -99,7 +99,7 @@ CFLAGS += $(CCVERBOSE)
DYNFLAGS += -M$(MAPFILE)
LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD)
-LDLIBS += -lsocket -lnsl -lmd5 -lc -lsecdb $(LAZYLIBS)
+LDLIBS += -lsocket -lnsl -lmd -lc -lsecdb $(LAZYLIBS)
lint := LAZYLIBS = -ltsol
COMDIR= ../common
diff --git a/usr/src/lib/libinetsvc/Makefile.com b/usr/src/lib/libinetsvc/Makefile.com
index 2bb617480d..6ea2c906c6 100644
--- a/usr/src/lib/libinetsvc/Makefile.com
+++ b/usr/src/lib/libinetsvc/Makefile.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -34,7 +33,7 @@ include ../../Makefile.lib
LIBS = $(DYNLIB) $(LINTLIB)
$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
-LDLIBS += -lscf -lc -lsocket -lnsl -lmd5 -luutil
+LDLIBS += -lscf -lc -lsocket -lnsl -lmd -luutil
SRCDIR = ../common
MAPDIR = ../spec/$(TRANSMACH)
diff --git a/usr/src/lib/libldap4/Makefile.com b/usr/src/lib/libldap4/Makefile.com
index d663656758..f1ba53072f 100644
--- a/usr/src/lib/libldap4/Makefile.com
+++ b/usr/src/lib/libldap4/Makefile.com
@@ -1,5 +1,5 @@
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -72,7 +72,7 @@ LOCFLAGS += -D_SYS_STREAM_H -D_REENTRANT -DSVR4 -DSUNW_OPTIONS \
CPPFLAGS = $(LOCFLAGS) $(CPPFLAGS.master)
CFLAGS += $(CCVERBOSE)
DYNFLAGS += -M $(MAPFILE)
-LDLIBS += -lsocket -lnsl -lresolv -lc -lmd5
+LDLIBS += -lsocket -lnsl -lresolv -lc -lmd
.KEEP_STATE:
diff --git a/usr/src/lib/libldap5/Makefile.com b/usr/src/lib/libldap5/Makefile.com
index a90c72761d..1874b19a76 100644
--- a/usr/src/lib/libldap5/Makefile.com
+++ b/usr/src/lib/libldap5/Makefile.com
@@ -120,7 +120,7 @@ SPECMAPFILE = $(MAPDIR)/mapfile
CFLAGS += $(CCVERBOSE) $(LOCFLAGS)
CFLAGS64 += $(LOCFLAGS)
-LDLIBS += -lsasl -lsocket -lnsl -lmd5 -lc
+LDLIBS += -lsasl -lsocket -lnsl -lmd -lc
.KEEP_STATE:
diff --git a/usr/src/lib/libmd/Makefile b/usr/src/lib/libmd/Makefile
new file mode 100644
index 0000000000..8d883853e6
--- /dev/null
+++ b/usr/src/lib/libmd/Makefile
@@ -0,0 +1,64 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libmd/Makefile
+#
+
+include ../Makefile.lib
+
+$(SPARC_BLD)PLATFORMS= sun4u sun4v
+
+SUBDIRS= $(MACH) $(PLATFORMS)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+HDRS = md4.h md5.h sha1.h sha2.h
+HDRDIR = common
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+lint := TARGET= lint
+
+.KEEP_STATE:
+
+.PARALLEL: $(MACH) $(MACH64) $(PLATFORMS)
+
+all install: spec .WAIT $(SUBDIRS)
+
+clean clobber: $(SUBDIRS)
+
+lint: $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+spec $(MACH) $(MACH64) $(PLATFORMS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+FRC:
+
+include ../Makefile.targ
diff --git a/usr/src/lib/libmd/Makefile.com b/usr/src/lib/libmd/Makefile.com
new file mode 100644
index 0000000000..d872a0c83e
--- /dev/null
+++ b/usr/src/lib/libmd/Makefile.com
@@ -0,0 +1,124 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libmd/Makefile.com
+#
+
+# $LIBRARY is set in lower makefiles so we can have platform and
+# processor optimised versions of this library via libmd_psr and libmd_hwcapN
+
+#LIBRARY= libmd.a
+VERS= .1
+
+OBJECTS= md4.o md5.o sha1.o sha2.o
+
+# Use $(SRC) to include makefiles rather than ../../ because the
+# platform subdirs are one level deeper so it would be ../../../ for them
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.rootfs
+
+LIBS = $(DYNLIB) $(LINTLIB)
+SRCS = \
+ $(COMDIR)/md4/md4.c \
+ $(COMDIR)/md5/md5.c \
+ $(COMDIR)/sha1/sha1.c \
+ $(COMDIR)/sha2/sha2.c
+
+COMDIR= $(SRC)/common/crypto
+
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+LDLIBS += -lc
+
+SRCDIR = ../common
+COMDIR = $(SRC)/common/crypto
+MAPDIR = ../spec/$(TRANSMACH)
+SPECMAPFILE = $(MAPDIR)/mapfile
+
+CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS)
+CFLAGS64 += $(C_BIGPICFLAGS)
+CPPFLAGS += -I$(SRCDIR)
+
+# The md5 and sha1 code is very careful about data alignment
+# but lint doesn't know that, so just shut lint up.
+LINTFLAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
+LINTFLAGS64 += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
+
+
+ROOTLINT= $(LINTSRC:%=$(ROOTLIBDIR)/%)
+
+.KEEP_STATE:
+
+all: $(LIBS) fnamecheck
+
+lint: lintcheck
+
+pics/%.o: $(COMDIR)/md4/%.c
+ $(COMPILE.c) -I$(COMDIR)/md4 -o $@ $<
+ $(POST_PROCESS_O)
+
+pics/%.o: $(COMDIR)/md5/%.c
+ $(COMPILE.c) -I$(COMDIR)/md5 $(INLINES) -o $@ $<
+ $(POST_PROCESS_O)
+
+pics/%.o: $(COMDIR)/sha1/%.c
+ $(COMPILE.c) -I$(COMDIR)/sha1 -o $@ $<
+ $(POST_PROCESS_O)
+
+pics/%.o: $(COMDIR)/sha1/sparc/$(PLATFORM)/sha1_asm.s
+ $(COMPILE.s) -P -DPIC -D_ASM -o $@ $<
+ $(POST_PROCESS_O)
+
+pics/%.o: $(COMDIR)/sha2/%.c
+ $(COMPILE.c) -I$(COMDIR)/sha2 -o $@ $<
+ $(POST_PROCESS_O)
+
+#
+# Used when building links in /platform/$(PLATFORM)/lib for libmd_psr.so.1
+#
+
+LIBMD_PSR_DIRS = $(LINKED_PLATFORMS:%=$(ROOT_PLAT_DIR)/%/lib)
+LIBMD_PSR_LINKS = $(LINKED_PLATFORMS:%=$(ROOT_PLAT_DIR)/%/lib/$(MODULE))
+
+LIBMD_PSR64_DIRS = $(LINKED_PLATFORMS:%=$(ROOT_PLAT_DIR)/%/lib/$(MACH64))
+LIBMD_PSR64_LINKS = $(LINKED_PLATFORMS:%=$(ROOT_PLAT_DIR)/%/lib/$(MACH64)/$(MODULE))
+
+INS.slink6 = $(RM) -r $@; $(SYMLINK) ../../$(PLATFORM)/lib/$(MODULE) $@ $(CHOWNLINK) $(CHGRPLINK)
+
+INS.slink64 = $(RM) -r $@; $(SYMLINK) ../../../$(PLATFORM)/lib/$(MACH64)/$(MODULE) $@ $(CHOWNLINK) $(CHGRPLINK)
+
+$(LIBMD_PSR_DIRS):
+ -$(INS.dir.root.bin)
+
+$(LIBMD_PSR_LINKS): $(LIBMD_PSR_DIRS)
+ -$(INS.slink6)
+
+$(LIBMD_PSR64_DIRS):
+ -$(INS.dir.root.bin)
+
+$(LIBMD_PSR64_LINKS): $(LIBMD_PSR64_DIRS)
+ -$(INS.slink64)
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/libmd/amd64/Makefile b/usr/src/lib/libmd/amd64/Makefile
new file mode 100644
index 0000000000..217f07b1d8
--- /dev/null
+++ b/usr/src/lib/libmd/amd64/Makefile
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY= libmd.a
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libmd/common/llib-lmd b/usr/src/lib/libmd/common/llib-lmd
new file mode 100644
index 0000000000..1d61afcff5
--- /dev/null
+++ b/usr/src/lib/libmd/common/llib-lmd
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <md5.h>
+#include <sha1.h>
+#include <sha2.h>
+#include <md4.h>
diff --git a/usr/src/cmd/volmgt/vold/md4.h b/usr/src/lib/libmd/common/md4.h
index 13d19b54c9..4772880634 100644
--- a/usr/src/cmd/volmgt/vold/md4.h
+++ b/usr/src/lib/libmd/common/md4.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1992 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,14 +41,14 @@ extern "C" {
/* MD4 context. */
typedef struct {
- u_long state[4]; /* state (ABCD) */
- u_long count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ ulong_t state[4]; /* state (ABCD) */
+ ulong_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD4_CTX;
void MD4Init(MD4_CTX *);
-void MD4Update(MD4_CTX *, unsigned char *, unsigned int);
-void MD4Final(unsigned char [16], MD4_CTX *);
+void MD4Update(MD4_CTX *, const void *_RESTRICT_KYWD, size_t);
+void MD4Final(void *, MD4_CTX *);
#ifdef __cplusplus
}
diff --git a/usr/src/head/md5.h b/usr/src/lib/libmd/common/md5.h
index b8d278d3d5..39525cf355 100644
--- a/usr/src/head/md5.h
+++ b/usr/src/lib/libmd/common/md5.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1999 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,7 +41,7 @@
extern "C" {
#endif
-void md5_calc(unsigned char *, unsigned char *, unsigned int);
+void md5_calc(void *, const void*, unsigned int);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libmd/common/sha1.h b/usr/src/lib/libmd/common/sha1.h
new file mode 100644
index 0000000000..241f1008d3
--- /dev/null
+++ b/usr/src/lib/libmd/common/sha1.h
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SHA1_H
+#define _SHA1_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/sha1.h>
+
+#endif /* _SHA1_H */
diff --git a/usr/src/lib/libmd/common/sha2.h b/usr/src/lib/libmd/common/sha2.h
new file mode 100644
index 0000000000..d19e2253b0
--- /dev/null
+++ b/usr/src/lib/libmd/common/sha2.h
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SHA2_H
+#define _SHA2_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/sha2.h>
+
+#endif /* _SHA2_H */
diff --git a/usr/src/lib/libmd/i386/Makefile b/usr/src/lib/libmd/i386/Makefile
new file mode 100644
index 0000000000..2b05624aa1
--- /dev/null
+++ b/usr/src/lib/libmd/i386/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+LIBRARY= libmd.a
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libmd/inc.flg b/usr/src/lib/libmd/inc.flg
new file mode 100644
index 0000000000..2652430b84
--- /dev/null
+++ b/usr/src/lib/libmd/inc.flg
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+find_files "s.*" usr/src/common/crypto/md4
+find_files "s.*" usr/src/common/crypto/md5
+find_files "s.*" usr/src/common/crypto/sha1
+find_files "s.*" usr/src/common/crypto/sha2
diff --git a/usr/src/lib/libmd/sparc/Makefile b/usr/src/lib/libmd/sparc/Makefile
new file mode 100644
index 0000000000..ccce8c78b2
--- /dev/null
+++ b/usr/src/lib/libmd/sparc/Makefile
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+
+LIBRARY= libmd.a
+
+include ../Makefile.com
+
+DYNFLAGS += -Wl,-f/platform/\$$PLATFORM/lib/$(DYNLIBPSR)
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libmd/sparcv9/Makefile b/usr/src/lib/libmd/sparcv9/Makefile
new file mode 100644
index 0000000000..6b3d51b1ea
--- /dev/null
+++ b/usr/src/lib/libmd/sparcv9/Makefile
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+
+LIBRARY= libmd.a
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+DYNFLAGS += -Wl,-f/platform/\$$PLATFORM/lib/$(MACH64)/$(DYNLIBPSR)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libmd/spec/Makefile b/usr/src/lib/libmd/spec/Makefile
new file mode 100644
index 0000000000..98e4eb2a33
--- /dev/null
+++ b/usr/src/lib/libmd/spec/Makefile
@@ -0,0 +1,29 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+include $(SRC)/lib/Makefile.spec.arch
+
+$(SPARC_BLD)SUBDIRS += sun4u sun4v
diff --git a/usr/src/lib/libmd/spec/Makefile.targ b/usr/src/lib/libmd/spec/Makefile.targ
new file mode 100644
index 0000000000..6f966d7486
--- /dev/null
+++ b/usr/src/lib/libmd/spec/Makefile.targ
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+LIBRARY= libmd.a
+VERS= .1
+
+OBJECTS= md.o
+
+SPECCPP += -I../../
diff --git a/usr/src/lib/libmd/spec/amd64/Makefile b/usr/src/lib/libmd/spec/amd64/Makefile
new file mode 100644
index 0000000000..a474b4b09b
--- /dev/null
+++ b/usr/src/lib/libmd/spec/amd64/Makefile
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+.KEEP_STATE:
+
+install: $(ROOTABILIB64)
diff --git a/usr/src/lib/libmd/spec/i386/Makefile b/usr/src/lib/libmd/spec/i386/Makefile
new file mode 100644
index 0000000000..4dd0d6208e
--- /dev/null
+++ b/usr/src/lib/libmd/spec/i386/Makefile
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libmd5/spec/i386/Makefile
+#
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB)
diff --git a/usr/src/lib/libmd/spec/md.spec b/usr/src/lib/libmd/spec/md.spec
new file mode 100644
index 0000000000..7fc227873e
--- /dev/null
+++ b/usr/src/lib/libmd/spec/md.spec
@@ -0,0 +1,192 @@
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+function MD5Init
+include <md5.h>
+declaration void MD5Init(MD5_CTX *context)
+version SUNW_1.1
+end
+
+function MD5Update
+include <md5.h>
+declaration void MD5Update(MD5_CTX *context, \
+ const void *input, \
+ unsigned int inputLen)
+version SUNW_1.1
+end
+
+function MD5Final
+include <md5.h>
+declaration void MD5Final(void *digest, MD5_CTX *context)
+version SUNW_1.1
+end
+
+function md5_calc
+declaration void md5_calc(void *output, \
+ const void *input, \
+ unsigned int inlen)
+version SUNW_1.1
+end
+
+function SHA1Init
+include <sha1.h>
+declaration void SHA1Init(SHA1_CTX *context)
+version SUNW_1.1
+end
+
+function SHA1Update
+include <sha1.h>
+declaration void SHA1Update(SHA1_CTX *context, \
+ const void *input, \
+ unsigned int inputLen)
+version SUNW_1.1
+end
+
+function SHA1Final
+include <sha1.h>
+declaration void SHA1Final(void *, SHA1_CTX *context)
+version SUNW_1.1
+end
+
+function SHA1Init
+include <sha1.h>
+declaration void SHA1Init(SHA1_CTX *context)
+version SUNW_1.1
+end
+
+function SHA1Update
+include <sha1.h>
+declaration void SHA1Update(SHA1_CTX *context, \
+ const void *input, \
+ unsigned int inputLen)
+version SUNW_1.1
+end
+
+function SHA1Final
+include <sha1.h>
+declaration void SHA1Final(void *digest, SHA1_CTX *context)
+version SUNW_1.1
+end
+
+function SHA2Init
+include <sha2.h>
+declaration void SHA2Init(uint64_t mech, SHA2_CTX *context)
+version SUNW_1.1
+end
+
+function SHA2Update
+include <sha2.h>
+declaration void SHA2Update(SHA2_CTX *context, \
+ const void *input, \
+ size_t inputLen)
+version SUNW_1.1
+end
+
+function SHA2Final
+include <sha2.h>
+declaration void SHA2Final(void *digest, SHA2_CTX *context)
+version SUNW_1.1
+end
+
+function SHA256Init
+include <sha2.h>
+declaration void SHA2Init(uint64_t mech, SHA2_CTX *context)
+version SUNW_1.1
+end
+
+function SHA256Update
+include <sha2.h>
+declaration void SHA2Update(SHA2_CTX *context, \
+ const void *input, \
+ size_t inputLen)
+version SUNW_1.1
+end
+
+function SHA256Final
+include <sha2.h>
+declaration void SHA256Final(void *digest, SHA256_CTX *context)
+version SUNW_1.1
+end
+
+function SHA384Init
+include <sha2.h>
+declaration void SHA384Init(uint64_t mech, SHA384_CTX *context)
+version SUNW_1.1
+end
+
+function SHA384Update
+include <sha2.h>
+declaration void SHA384Update(SHA384_CTX *context, \
+ const void *input, \
+ size_t inputLen)
+version SUNW_1.1
+end
+
+function SHA384Final
+include <sha2.h>
+declaration void SHA384Final(void *digest, SHA384_CTX *context)
+version SUNW_1.1
+end
+
+function SHA512Init
+include <sha2.h>
+declaration void SHA512Init(uint64_t mech, SHA512_CTX *context)
+version SUNW_1.1
+end
+
+function SHA512Update
+include <sha2.h>
+declaration void SHA512Update(SHA512_CTX *context, \
+ const void *input, \
+ size_t inputLen)
+version SUNW_1.1
+end
+
+function SHA512Final
+include <sha2.h>
+declaration void SHA512Final(void *digest, SHA512_CTX *context)
+version SUNW_1.1
+end
+
+function MD4Init
+include <md4.h>
+declaration void MD4Init(MD4_CTX *context)
+version SUNW_1.1
+end
+
+function MD4Update
+include <md4.h>
+declaration void MD4Update(MD4_CTX *context, \
+ const void *input, \
+ unsigned int inputLen)
+version SUNW_1.1
+end
+
+function MD4Final
+include <md4.h>
+declaration void MD4Final(void *digest, MD4_CTX *context)
+version SUNW_1.1
+end
diff --git a/usr/src/lib/libmd/spec/sparc/Makefile b/usr/src/lib/libmd/spec/sparc/Makefile
new file mode 100644
index 0000000000..b03a759294
--- /dev/null
+++ b/usr/src/lib/libmd/spec/sparc/Makefile
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB)
diff --git a/usr/src/lib/libmd/spec/sparcv9/Makefile b/usr/src/lib/libmd/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..b8c5ba76bb
--- /dev/null
+++ b/usr/src/lib/libmd/spec/sparcv9/Makefile
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libmd/spec/sparcv9/Makefile
+#
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB64)
diff --git a/usr/src/lib/libmd/spec/versions b/usr/src/lib/libmd/spec/versions
new file mode 100644
index 0000000000..5bfbaae1ed
--- /dev/null
+++ b/usr/src/lib/libmd/spec/versions
@@ -0,0 +1,37 @@
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+sparc {
+ SUNW_1.1;
+}
+sparcv9 {
+ SUNW_1.1;
+}
+i386 {
+ SUNW_1.1;
+}
+amd64 {
+ SUNW_1.1;
+}
diff --git a/usr/src/lib/libmd/sun4u/Makefile b/usr/src/lib/libmd/sun4u/Makefile
new file mode 100644
index 0000000000..b65f30de75
--- /dev/null
+++ b/usr/src/lib/libmd/sun4u/Makefile
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+include $(SRC)/Makefile.master
+
+SUBDIRS= $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+install := TARGET= install
+
+.KEEP_STATE:
+
+.PARALLEL: $(MACH) $(MACH64)
+
+all clean clobber lint install: $(SUBDIRS)
+
+$(MACH) $(MACH64): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/lib/libmd/sun4u/Makefile.com b/usr/src/lib/libmd/sun4u/Makefile.com
new file mode 100644
index 0000000000..c483e9b540
--- /dev/null
+++ b/usr/src/lib/libmd/sun4u/Makefile.com
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+LIBRARY= libmd_psr.a
+
+include $(SRC)/Makefile.psm
+include ../Makefile.links
+include ../../Makefile.com
+
+LIBS= $(DYNLIB)
+
+CFLAGS += -xarch=v8plusa
+CPPFLAGS += -D$(PLATFORM) -DVIS_SHA1
+ASFLAGS = -P $(ASDEFS)
+
+INLINES= $(COMDIR)/md5/$(MACH)/$(PLATFORM)/byteswap.il
+
+# XXX This seems wrong since we explicitly set LIBS to be DYNLIB only
+$(LINTLIB):= SRCS= ../../common/llib-lmd
diff --git a/usr/src/lib/libmd/sun4u/Makefile.links b/usr/src/lib/libmd/sun4u/Makefile.links
new file mode 100644
index 0000000000..d1ff848458
--- /dev/null
+++ b/usr/src/lib/libmd/sun4u/Makefile.links
@@ -0,0 +1,66 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libmd/Makefile.sun4u.links
+#
+#
+# Used when building links in /platform/sun4u/lib
+#
+LINKED_PLATFORMS = SUNW,Ultra-2
+LINKED_PLATFORMS += SUNW,Ultra-4
+LINKED_PLATFORMS += SUNW,Ultra-5_10
+LINKED_PLATFORMS += SUNW,Ultra-30
+LINKED_PLATFORMS += SUNW,Ultra-60
+LINKED_PLATFORMS += SUNW,Ultra-80
+LINKED_PLATFORMS += SUNW,Ultra-250
+LINKED_PLATFORMS += SUNW,Ultra-Enterprise
+LINKED_PLATFORMS += SUNW,Ultra-Enterprise-10000
+LINKED_PLATFORMS += SUNW,UltraAX-i2
+LINKED_PLATFORMS += SUNW,UltraSPARC-IIi-Netract
+LINKED_PLATFORMS += SUNW,UltraSPARC-IIe-NetraCT-40
+LINKED_PLATFORMS += SUNW,UltraSPARC-IIe-NetraCT-60
+LINKED_PLATFORMS += SUNW,Sun-Blade-100
+LINKED_PLATFORMS += SUNW,Sun-Blade-1000
+LINKED_PLATFORMS += SUNW,Sun-Blade-1500
+LINKED_PLATFORMS += SUNW,Sun-Blade-2500
+LINKED_PLATFORMS += SUNW,A70
+LINKED_PLATFORMS += SUNW,Sun-Fire
+LINKED_PLATFORMS += SUNW,Sun-Fire-V215
+LINKED_PLATFORMS += SUNW,Sun-Fire-V240
+LINKED_PLATFORMS += SUNW,Sun-Fire-V250
+LINKED_PLATFORMS += SUNW,Sun-Fire-V440
+LINKED_PLATFORMS += SUNW,Sun-Fire-V445
+LINKED_PLATFORMS += SUNW,Sun-Fire-280R
+LINKED_PLATFORMS += SUNW,Sun-Fire-15000
+LINKED_PLATFORMS += SUNW,Sun-Fire-880
+LINKED_PLATFORMS += SUNW,Sun-Fire-480R
+LINKED_PLATFORMS += SUNW,Sun-Fire-V890
+LINKED_PLATFORMS += SUNW,Sun-Fire-V490
+LINKED_PLATFORMS += SUNW,Serverblade1
+LINKED_PLATFORMS += SUNW,Netra-T12
+LINKED_PLATFORMS += SUNW,Netra-T4
+LINKED_PLATFORMS += SUNW,Netra-CP2300
+LINKED_PLATFORMS += SUNW,Netra-CP3010
diff --git a/usr/src/lib/libmd/sun4u/sparc/Makefile b/usr/src/lib/libmd/sun4u/sparc/Makefile
new file mode 100644
index 0000000000..cac5b1d58d
--- /dev/null
+++ b/usr/src/lib/libmd/sun4u/sparc/Makefile
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+CLASS = 32
+PLATFORM = sun4u
+MODULE = libmd_psr.so.1
+
+include ../Makefile.com
+
+# Override OBJECTS here because each $MACH/$PLATFORM can have a different
+# set of algortithm optimisations and thus different source and object files.
+OBJECTS = md5.o sha1.o sha1_asm.o
+
+SPECMAPFILE=
+MAPFILE= mapfile
+DYNFLAGS += -M$(MAPFILE)
+
+ASFLAGS += -xarch=v8plusa -warn
+
+# Redefine shared object build rule to use $(LD) directly (this avoids .init
+# and .fini sections being added).
+
+BUILD.SO= $(LD) -o $@ -G $(DYNFLAGS) $(PICS) $(LDLIBS)
+
+$(DYNLIB): $(MAPFILE)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+$(ROOT_PSM_LIB_DIR)/% := FILEMODE = 755
+
+install: all $(LIBMD_PSR_LINKS) $(ROOT_PSM_LIBS)
+
+include $(SRC)/Makefile.psm.targ
diff --git a/usr/src/lib/libmd/sun4u/sparc/mapfile b/usr/src/lib/libmd/sun4u/sparc/mapfile
new file mode 100644
index 0000000000..509adf5315
--- /dev/null
+++ b/usr/src/lib/libmd/sun4u/sparc/mapfile
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+SUNW_1.1 {
+ global:
+ MD5Init;
+ MD5Update;
+ MD5Final;
+ SHA1Init;
+ SHA1Update;
+ SHA1Final;
+ local:
+ *;
+};
diff --git a/usr/src/lib/libmd/sun4u/sparcv9/Makefile b/usr/src/lib/libmd/sun4u/sparcv9/Makefile
new file mode 100644
index 0000000000..aca34d4c3c
--- /dev/null
+++ b/usr/src/lib/libmd/sun4u/sparcv9/Makefile
@@ -0,0 +1,60 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+CLASS = 64
+PLATFORM = sun4u
+MODULE = libmd_psr.so.1
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+# Override OBJECTS here because each $MACH/$PLATFORM can have a different
+# set of algortithm optimisations and thus different source and object files.
+OBJECTS = md5.o sha1.o sha1_asm.o
+
+SPECMAPFILE=
+MAPFILE= mapfile
+DYNFLAGS += -M$(MAPFILE)
+
+ASDEFS += -D__sparcv9
+ASFLAGS += -xarch=v9a $(AS_BIGPICFLAGS)
+
+# Redefine shared object build rule to use $(LD) directly (this avoids .init
+# and .fini sections being added).
+
+BUILD.SO= $(LD) -o $@ -G $(DYNFLAGS) $(PICS) $(LDLIBS)
+
+$(DYNLIB): $(MAPFILE)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+$(ROOT_PSM_LIB64_DIR)/% := FILEMODE = 755
+
+install: all $(LIBMD_PSR64_LINKS) $(ROOT_PSM_LIB64_DIR)/$(LIBS)
+
+include $(SRC)/Makefile.psm.targ
diff --git a/usr/src/lib/libmd/sun4u/sparcv9/mapfile b/usr/src/lib/libmd/sun4u/sparcv9/mapfile
new file mode 100644
index 0000000000..7687cc349f
--- /dev/null
+++ b/usr/src/lib/libmd/sun4u/sparcv9/mapfile
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+SUNW_1.1 {
+ global:
+ MD5Init;
+ MD5Update;
+ MD5Final;
+ SHA1Init;
+ SHA1Update;
+ SHA1Final;
+ local:
+ *;
+};
diff --git a/usr/src/lib/libmd/sun4v/Makefile b/usr/src/lib/libmd/sun4v/Makefile
new file mode 100644
index 0000000000..b65f30de75
--- /dev/null
+++ b/usr/src/lib/libmd/sun4v/Makefile
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+include $(SRC)/Makefile.master
+
+SUBDIRS= $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+install := TARGET= install
+
+.KEEP_STATE:
+
+.PARALLEL: $(MACH) $(MACH64)
+
+all clean clobber lint install: $(SUBDIRS)
+
+$(MACH) $(MACH64): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/lib/libmd/sun4v/Makefile.com b/usr/src/lib/libmd/sun4v/Makefile.com
new file mode 100644
index 0000000000..bef660abbc
--- /dev/null
+++ b/usr/src/lib/libmd/sun4v/Makefile.com
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+LIBRARY= libmd_psr.a
+
+include $(SRC)/Makefile.psm
+include ../Makefile.links
+include ../../Makefile.com
+
+LIBS= $(DYNLIB)
+
+CFLAGS += -xarch=v8plusa
+CPPFLAGS += -D$(PLATFORM)
+ASFLAGS = -P $(ASDEFS)
+
+INLINES= $(COMDIR)/md5/$(MACH)/$(PLATFORM)/byteswap.il
+
+# XXX This seems wrong since we explicitly set LIBS to be DYNLIB only
+$(LINTLIB):= SRCS= ../../common/llib-lmd
diff --git a/usr/src/lib/libmd/sun4v/Makefile.links b/usr/src/lib/libmd/sun4v/Makefile.links
new file mode 100644
index 0000000000..e03b1e1b15
--- /dev/null
+++ b/usr/src/lib/libmd/sun4v/Makefile.links
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libmd/Makefile.sun4v.links
+#
+#
+# Used when building links in /platform/sun4v/lib
+#
+LINKED_PLATFORMS = SUNW,Sun-Fire-T200
diff --git a/usr/src/lib/libmd/sun4v/sparc/Makefile b/usr/src/lib/libmd/sun4v/sparc/Makefile
new file mode 100644
index 0000000000..2633839ee3
--- /dev/null
+++ b/usr/src/lib/libmd/sun4v/sparc/Makefile
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+CLASS = 32
+PLATFORM = sun4v
+MODULE = libmd_psr.so.1
+
+include ../Makefile.com
+
+# Override OBJECTS here because each $MACH/$PLATFORM can have a different
+# set of algortithm optimisations and thus different source and object files.
+OBJECTS = md5.o
+
+SPECMAPFILE=
+MAPFILE= mapfile
+DYNFLAGS += -M$(MAPFILE)
+
+ASFLAGS += -xarch=v8plusa -warn
+
+# Redefine shared object build rule to use $(LD) directly (this avoids .init
+# and .fini sections being added).
+
+BUILD.SO= $(LD) -o $@ -G $(DYNFLAGS) $(PICS) $(LDLIBS)
+
+$(DYNLIB): $(MAPFILE)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+$(ROOT_PSM_LIB_DIR)/% := FILEMODE = 755
+
+install: all $(LIBMD_PSR_LINKS) $(ROOT_PSM_LIBS)
+
+include $(SRC)/Makefile.psm.targ
diff --git a/usr/src/lib/libmd/sun4v/sparc/mapfile b/usr/src/lib/libmd/sun4v/sparc/mapfile
new file mode 100644
index 0000000000..e6d7fddc28
--- /dev/null
+++ b/usr/src/lib/libmd/sun4v/sparc/mapfile
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+SUNW_1.1 {
+ global:
+ MD5Init;
+ MD5Update;
+ MD5Final;
+ local:
+ *;
+};
diff --git a/usr/src/lib/libmd/sun4v/sparcv9/Makefile b/usr/src/lib/libmd/sun4v/sparcv9/Makefile
new file mode 100644
index 0000000000..ac4ff682d3
--- /dev/null
+++ b/usr/src/lib/libmd/sun4v/sparcv9/Makefile
@@ -0,0 +1,60 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+CLASS = 64
+PLATFORM = sun4v
+MODULE = libmd_psr.so.1
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+# Override OBJECTS here because each $MACH/$PLATFORM can have a different
+# set of algortithm optimisations and thus different source and object files.
+OBJECTS = md5.o
+
+SPECMAPFILE=
+MAPFILE= mapfile
+DYNFLAGS += -M$(MAPFILE)
+
+ASDEFS += -D__sparcv9
+ASFLAGS += -xarch=v9a $(AS_PICFLAGS)
+
+# Redefine shared object build rule to use $(LD) directly (this avoids .init
+# and .fini sections being added).
+
+BUILD.SO= $(LD) -o $@ -G $(DYNFLAGS) $(PICS) $(LDLIBS)
+
+$(DYNLIB): $(MAPFILE)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+$(ROOT_PSM_LIB64_DIR)/% := FILEMODE = 755
+
+install: all $(LIBMD_PSR64_LINKS) $(ROOT_PSM_LIB64_DIR)/$(LIBS)
+
+include $(SRC)/Makefile.psm.targ
diff --git a/usr/src/lib/libmd/sun4v/sparcv9/mapfile b/usr/src/lib/libmd/sun4v/sparcv9/mapfile
new file mode 100644
index 0000000000..e6d7fddc28
--- /dev/null
+++ b/usr/src/lib/libmd/sun4v/sparcv9/mapfile
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+SUNW_1.1 {
+ global:
+ MD5Init;
+ MD5Update;
+ MD5Final;
+ local:
+ *;
+};
diff --git a/usr/src/lib/libmd5/Makefile b/usr/src/lib/libmd5/Makefile
index 11f3939e73..973a0bc83b 100644
--- a/usr/src/lib/libmd5/Makefile
+++ b/usr/src/lib/libmd5/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,34 +18,31 @@
#
# CDDL HEADER END
#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1999 by Sun Microsystems, Inc.
-# All rights reserved.
+# ident "%Z%%M% %I% %E% SMI"
#
# lib/libmd5/Makefile
-#
include $(SRC)/Makefile.master
-SUBDIRS= spec .WAIT $(MACH) $(BUILD64) $(MACH64)
+SUBDIRS= $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
all := TARGET= all
clean := TARGET= clean
clobber := TARGET= clobber
-lint := TARGET= lint
install := TARGET= install
.KEEP_STATE:
.PARALLEL: $(MACH) $(MACH64)
-all clean clobber lint install: $(SUBDIRS)
+all clean clobber install: $(SUBDIRS)
-spec $(MACH) $(MACH64): FRC
+$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
-_msg install_h check:
-
FRC:
diff --git a/usr/src/lib/libmd5/Makefile.com b/usr/src/lib/libmd5/Makefile.com
index dc87dce0b6..1ef3db8a31 100644
--- a/usr/src/lib/libmd5/Makefile.com
+++ b/usr/src/lib/libmd5/Makefile.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -31,51 +30,31 @@
LIBRARY= libmd5.a
VERS= .1
-OBJECTS= md5.o
-COMMON= $(SRC)/common/crypto/md5
-
include ../../Makefile.lib
-
-# install this library in the root filesystem
include ../../Makefile.rootfs
-LIBS= $(DYNLIB) $(LINTLIB)
+MAPFILES= $(SRCDIR)/mapfile-vers $(MAPFILE-FLTR)
+MAPOPTS= $(MAPFILES:%=-M %)
-# Macros to help build the shared object
-MAPFILE= $(MAPDIR)/mapfile
-DYNFLAGS += -M$(MAPFILE)
-CPPFLAGS += -D__RESTRICT
-CFLAGS += $(CCVERBOSE)
+DYNFLAGS += -F libmd.so.1 $(MAPOPTS)
-DYNFLAGS += $(BDIRECT)
-LDLIBS += -lc
+LIBS = $(DYNLIB) $(LINTLIB)
-# Macros to help build the lint library
-LINTSRC= $(LINTLIB:%.ln=%)
-$(LINTLIB) := SRCS= ../$(LINTSRC)
-SRCS= $(OBJECTS:%.o=$(COMMON)/%.c)
-ROOTLINT= $(LINTSRC:%=$(ROOTLIBDIR)/%)
-$(ROOTLIBDIR)/%: ../%
- $(INS.file)
+SRCDIR = ../common
+$(LINTLIB) := SRCS = $(SRCDIR)/llib-lmd5
-# The md5 code is very careful about data alignment
-# but lint doesn't know that, so just shut lint up.
-lint := LINTFLAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-lint := LINTFLAGS64 += -erroff=E_BAD_PTR_CAST_ALIGN
-.KEEP_STATE:
+# Redefine shared object build rule to use $(LD) directly (this avoids .init
+# and .fini sections being added). Also, since there are no OBJECTS, turn
+# off CTF.
-$(DYNLIB): $(MAPFILE)
+BUILD.SO= $(LD) -o $@ -G $(DYNFLAGS)
+CTFMERGE_LIB= :
-$(MAPFILE):
- @cd $(MAPDIR); pwd; $(MAKE) mapfile
-
-all: $(LIBS) fnamecheck
+.KEEP_STATE:
-lint: lintcheck
+all: $(LIBS)
-include $(SRC)/lib/Makefile.targ
+include ../../Makefile.targ
-pics/%.o: $(COMMON)/%.c
- $(COMPILE.c) -o $@ $<
- $(POST_PROCESS_O)
+$(DYNLIB): $(MAPFILES)
diff --git a/usr/src/lib/libmd5/amd64/Makefile b/usr/src/lib/libmd5/amd64/Makefile
index b294fed674..bb52c69dfe 100644
--- a/usr/src/lib/libmd5/amd64/Makefile
+++ b/usr/src/lib/libmd5/amd64/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -25,9 +24,12 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
+# lib/libmd5/amd64/Makefile
+#
-MAPDIR= ../spec/amd64
include ../Makefile.com
-include $(SRC)/lib/Makefile.lib.64
+include ../../Makefile.lib.64
+
+BUILD.SO= $(LD) -o $@ -G -64 $(DYNFLAGS)
install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libmd5/llib-lmd5 b/usr/src/lib/libmd5/common/llib-lmd5
index ebbf9a44a4..0235ae5c81 100644
--- a/usr/src/lib/libmd5/llib-lmd5
+++ b/usr/src/lib/libmd5/common/llib-lmd5
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -23,16 +22,10 @@
/* PROTOLIB1 */
/*
- * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#include <sys/types.h>
#include <md5.h>
-
-void MD5Init(MD5_CTX *);
-void MD5Update(MD5_CTX *, const void *, unsigned int);
-void MD5Final(unsigned char [16], MD5_CTX *);
-void md5_calc(unsigned char *, unsigned char *, unsigned int);
diff --git a/usr/src/lib/libmd5/common/mapfile-vers b/usr/src/lib/libmd5/common/mapfile-vers
new file mode 100644
index 0000000000..00a62556a4
--- /dev/null
+++ b/usr/src/lib/libmd5/common/mapfile-vers
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# DO NOT TOUCH THIS FILE.
+# This file declares interfaces that are cast in stone.
+# The real interface is now libmd, libmd5 is just a filter library
+# for legacy reasons.
+# They offer interfaces that will never change.
+# DO NOT TOUCH THIS FILE.
+#
+
+
+SUNW_1.1 {
+ global:
+ MD5Init = FUNCTION;
+ MD5Update = FUNCTION;
+ MD5Final = FUNCTION;
+ md5_calc = FUNCTION;
+};
diff --git a/usr/src/lib/libmd5/sparc/Makefile b/usr/src/lib/libmd5/sparc/Makefile
index 689c36c4f8..16ccc40281 100644
--- a/usr/src/lib/libmd5/sparc/Makefile
+++ b/usr/src/lib/libmd5/sparc/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -28,9 +27,6 @@
# lib/libmd5/sparc/Makefile
#
-MAPDIR= ../spec/sparc
include ../Makefile.com
-DYNFLAGS += -Wl,-f/platform/\$$PLATFORM/lib/$(DYNLIBPSR)
-
install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libmd5/sparcv9/Makefile b/usr/src/lib/libmd5/sparcv9/Makefile
index 86e137098a..5e5b3dc6ab 100644
--- a/usr/src/lib/libmd5/sparcv9/Makefile
+++ b/usr/src/lib/libmd5/sparcv9/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -28,10 +27,9 @@
# lib/libmd5/sparcv9/Makefile
#
-MAPDIR= ../spec/sparcv9
include ../Makefile.com
-include $(SRC)/lib/Makefile.lib.64
+include ../../Makefile.lib.64
-DYNFLAGS += -Wl,-f/platform/\$$PLATFORM/lib/sparcv9/$(DYNLIBPSR)
+BUILD.SO= $(LD) -o $@ -G -64 $(DYNFLAGS)
install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libnsl/Makefile.com b/usr/src/lib/libnsl/Makefile.com
index 0159a59cba..9b845c9daf 100644
--- a/usr/src/lib/libnsl/Makefile.com
+++ b/usr/src/lib/libnsl/Makefile.com
@@ -207,8 +207,8 @@ CPPFLAGS += -I$(SRC)/lib/libnsl/dial
CFLAGS += -v
-LAZYLIBS = $(ZLAZYLOAD) -lmp -lmd5 -lscf $(ZNOLAZYLOAD)
-lint := LAZYLIBS = -lmd5
+LAZYLIBS = $(ZLAZYLOAD) -lmp -lmd -lscf $(ZNOLAZYLOAD)
+lint := LAZYLIBS = -lmd
LDLIBS += $(LAZYLIBS) -lc
DYNFLAGS += $(MAPOPTS)
diff --git a/usr/src/lib/libresolv2/dnssafe/Makefile.com b/usr/src/lib/libresolv2/dnssafe/Makefile.com
index ff6c66201a..c3c12e49bd 100644
--- a/usr/src/lib/libresolv2/dnssafe/Makefile.com
+++ b/usr/src/lib/libresolv2/dnssafe/Makefile.com
@@ -41,7 +41,7 @@ include ../../../Makefile.lib
LIBNAME= $(LIBRARY:%.a=%)
LIBS= $(DYNLIB)
-LDLIBS += -lmd5 -lresolv -lc
+LDLIBS += -lmd -lresolv -lc
MAPDIR = ../spec/$(TRANSMACH)
SPECMAPFILE = $(MAPDIR)/mapfile
diff --git a/usr/src/lib/librt/Makefile.com b/usr/src/lib/librt/Makefile.com
index 2612ecdbff..1e93ff0b47 100644
--- a/usr/src/lib/librt/Makefile.com
+++ b/usr/src/lib/librt/Makefile.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -47,7 +46,7 @@ include ../../Makefile.lib
include ../../Makefile.rootfs
LIBS = $(DYNLIB) $(LINTLIB)
-LDLIBS += -laio -lmd5 -lc
+LDLIBS += -laio -lmd -lc
$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
SRCDIR= ../common
diff --git a/usr/src/lib/librt/common/pos4obj.c b/usr/src/lib/librt/common/pos4obj.c
index 2d6917ed33..f54a850907 100644
--- a/usr/src/lib/librt/common/pos4obj.c
+++ b/usr/src/lib/librt/common/pos4obj.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -44,7 +43,6 @@
#include "pos4.h"
#include "pos4obj.h"
-#define MD5LEN 16
#define HASHSTRLEN 32
static char *__pos4obj_name(const char *, const char *);
@@ -99,7 +97,7 @@ __pos4obj_name(const char *path, const char *type)
size_t len;
char *dfile;
unsigned char hashbuf[HASHSTRLEN + 1];
- unsigned char md5_digest[MD5LEN];
+ unsigned char md5_digest[MD5_DIGEST_LENGTH];
/*
* If the path is path_max - strlen(type) characters or less,
@@ -235,7 +233,7 @@ __pos4obj_md5toa(unsigned char *dest, unsigned char *src)
/* LINTED pointer cast may result in improper alignment */
p = (uint32_t *)src;
- for (i = 0; i < (MD5LEN / 4); i++)
+ for (i = 0; i < (MD5_DIGEST_LENGTH / 4); i++)
(void) snprintf((char *)dest + (i * 8), 9, "%.8x", *p++);
dest[HASHSTRLEN] = '\0';
diff --git a/usr/src/lib/libsasl/Makefile.com b/usr/src/lib/libsasl/Makefile.com
index cea9bf8530..a28a4f4c84 100644
--- a/usr/src/lib/libsasl/Makefile.com
+++ b/usr/src/lib/libsasl/Makefile.com
@@ -1,5 +1,5 @@
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -23,7 +23,7 @@ include ../../Makefile.lib
LIBS= $(DYNLIB) $(LINTLIB)
SRCS= $(SASLOBJS:%.o=../lib/%.c) $(COMMONOBJS:%.o=$(PLUGDIR)/%.c)
$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
-LDLIBS += -lsocket -lc -lmd5
+LDLIBS += -lsocket -lc -lmd
LINTFLAGS += -DPIC
LINTFLAGS64 += -DPIC
diff --git a/usr/src/lib/libwanbootutil/Makefile.com b/usr/src/lib/libwanbootutil/Makefile.com
index 044aad0c4c..23463dad43 100644
--- a/usr/src/lib/libwanbootutil/Makefile.com
+++ b/usr/src/lib/libwanbootutil/Makefile.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -39,7 +38,6 @@ LOC_SRCS = $(LOC_OBJS:%.o=$(LOC_DIR)/%.c)
# The crypto modules are located under usr/src/common.
CRYPTO_DIR = $(SRC)/common/net/wanboot/crypt
CRYPTO_OBJS = hmac_sha1.o \
- sha1.o \
aes.o \
des3.o \
des.o \
@@ -52,7 +50,7 @@ OBJECTS = $(LOC_OBJS) $(CRYPTO_OBJS)
include $(SRC)/lib/Makefile.lib
LIBS += $(LINTLIB)
-LDLIBS += -lc -lnsl
+LDLIBS += -lc -lnsl -lmd
# Must override SRCS from Makefile.lib since sources have
# multiple source directories.
diff --git a/usr/src/lib/libwanbootutil/spec/wanbootutil.spec b/usr/src/lib/libwanbootutil/spec/wanbootutil.spec
index d80977b2a3..b2e756c857 100644
--- a/usr/src/lib/libwanbootutil/spec/wanbootutil.spec
+++ b/usr/src/lib/libwanbootutil/spec/wanbootutil.spec
@@ -1,13 +1,12 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -132,18 +131,6 @@ function HMACFinal
version SUNWprivate_1.1
end
-function SHA1Init
-version SUNWprivate_1.1
-end
-
-function SHA1Update
-version SUNWprivate_1.1
-end
-
-function SHA1Final
-version SUNWprivate_1.1
-end
-
function wbio_nwrite
version SUNWprivate_1.1
end
diff --git a/usr/src/lib/pkcs11/Makefile.softtoken.com b/usr/src/lib/pkcs11/Makefile.softtoken.com
index 663d31d804..0a09b9523d 100644
--- a/usr/src/lib/pkcs11/Makefile.softtoken.com
+++ b/usr/src/lib/pkcs11/Makefile.softtoken.com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -72,8 +71,6 @@ BLOWFISH_COBJECTS = blowfish_cbc_crypt.o blowfish_impl.o
ARCFOUR_COBJECTS = arcfour_crypt.o
DES_COBJECTS = des_cbc_crypt.o des_impl.o des_ks.o
RSA_COBJECTS = rsa_impl.o
-SHA1_COBJECTS = sha1.o
-SHA2_COBJECTS = sha2.o
BIGNUM_COBJECTS = bignumimpl.o
AES_OBJECTS = $(AES_COBJECTS) $(AES_PSR_OBJECTS)
@@ -127,8 +124,6 @@ BLOWFISHDIR= $(SRC)/common/crypto/blowfish
ARCFOURDIR= $(SRC)/common/crypto/arcfour
DESDIR= $(SRC)/common/crypto/des
RSADIR= $(SRC)/common/crypto/rsa
-SHA1DIR= $(SRC)/common/crypto/sha1
-SHA2DIR= $(SRC)/common/crypto/sha2
BIGNUMDIR= $(SRC)/common/bignum
BERDIR= ../../../libldap5/sources/ldap/ber
@@ -152,7 +147,7 @@ SRCS = \
$(BIGNUM_PSR_SRCS)
LIBS = $(DYNLIB)
-LDLIBS += -lc -lmd5
+LDLIBS += -lc -lmd
MAPDIR = ../spec/$(TRANSMACH)
SPECMAPFILE = $(MAPDIR)/mapfile
diff --git a/usr/src/lib/pkcs11/Makefile.softtoken.sparc b/usr/src/lib/pkcs11/Makefile.softtoken.sparc
index c0ba8abdc6..a8045257e2 100644
--- a/usr/src/lib/pkcs11/Makefile.softtoken.sparc
+++ b/usr/src/lib/pkcs11/Makefile.softtoken.sparc
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -33,13 +32,11 @@ AES_PSR_OBJECTS = aes_crypt_sparc.o
ARCFOUR_PSR_OBJECTS = arcfour_crypt_sparc.o
DES_PSR_OBJECTS = des_crypt_sparc.o
RSA_PSR_OBJECTS =
-SHA1_PSR_OBJECTS = sha1_asm_sparc.o
BIGNUM_PSR_OBJECTS = mont_mulf_sparc.o
BIGNUM_CFG = -DUSE_FLOATING_POINT
include ../Makefile.com
CFLAGS += -Dsun4u
-pics/sha1.o := CFLAGS += -DVIS_SHA1
install: all $(ROOTLIBS) $(ROOTLINKS)
@@ -59,11 +56,6 @@ pics/des_crypt_sparc.o: $(DESDIR)/sun4u/des_crypt_asm.s
$(DESDIR)/sun4u/des_crypt_asm.s
$(POST_PROCESS_O)
-pics/sha1_asm_sparc.o: $(SHA1DIR)/sparc/sun4u/sha1_asm.s
- $(COMPILE.s) -K PIC -P -DPIC -D_ASM -xarch=v8plusa -o $@ \
- $(SHA1DIR)/sparc/sun4u/sha1_asm.s
- $(POST_PROCESS_O)
-
pics/mont_mulf_sparc.o: $(BIGNUMDIR)/sun4u/mont_mulf_v8plus.s
$(COMPILE.s) $(AS_BIGPICFLAGS) -xarch=v8plus -o $@ \
$(BIGNUMDIR)/sun4u/mont_mulf_v8plus.s
diff --git a/usr/src/lib/pkcs11/Makefile.softtoken.sparcv9 b/usr/src/lib/pkcs11/Makefile.softtoken.sparcv9
index 121e8919dc..d57a7c9163 100644
--- a/usr/src/lib/pkcs11/Makefile.softtoken.sparcv9
+++ b/usr/src/lib/pkcs11/Makefile.softtoken.sparcv9
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -33,14 +32,12 @@ AES_PSR_OBJECTS = aes_crypt_sparcv9.o
ARCFOUR_PSR_OBJECTS = arcfour_crypt_sparcv9.o
DES_PSR_OBJECTS = des_crypt_sparcv9.o
RSA_PSR_OBJECTS =
-SHA1_PSR_OBJECTS = sha1_asm_sparcv9.o
BIGNUM_PSR_OBJECTS = mont_mulf_sparcv9.o
BIGNUM_CFG = -DUSE_FLOATING_POINT
include ../Makefile.com
include ../../../Makefile.lib.64
CFLAGS64 += -Dsun4u
-pics/sha1.o := CFLAGS64 += -DVIS_SHA1
install: all $(ROOTLIBS64) $(ROOTLINKS64)
@@ -60,11 +57,6 @@ pics/des_crypt_sparcv9.o: $(DESDIR)/sun4u/des_crypt_asm.s
$(DESDIR)/sun4u/des_crypt_asm.s
$(POST_PROCESS_O)
-pics/sha1_asm_sparcv9.o: $(SHA1DIR)/sparc/sun4u/sha1_asm.s
- $(COMPILE.s) -K PIC -P -DPIC -D_ASM -xarch=v9a -o $@ \
- $(SHA1DIR)/sparc/sun4u/sha1_asm.s
- $(POST_PROCESS_O)
-
pics/mont_mulf_sparcv9.o: $(BIGNUMDIR)/sun4u/mont_mulf_v9.s
$(COMPILE.s) $(AS_BIGPICFLAGS) -xarch=v9 -o $@ $(BIGNUMDIR)/sun4u/mont_mulf_v9.s
$(POST_PROCESS_O)
diff --git a/usr/src/pkgdefs/SUNWarcr/prototype_com b/usr/src/pkgdefs/SUNWarcr/prototype_com
index 97ec6b58d5..09a3de0467 100644
--- a/usr/src/pkgdefs/SUNWarcr/prototype_com
+++ b/usr/src/pkgdefs/SUNWarcr/prototype_com
@@ -86,6 +86,8 @@ f none lib/llib-lintl 644 root bin
f none lib/llib-lintl.ln 644 root bin
f none lib/llib-lkstat 644 root bin
f none lib/llib-lkstat.ln 644 root bin
+f none lib/llib-lmd 644 root bin
+f none lib/llib-lmd.ln 644 root bin
f none lib/llib-lmd5 644 root bin
f none lib/llib-lmd5.ln 644 root bin
f none lib/llib-lnsl 644 root bin
diff --git a/usr/src/pkgdefs/SUNWarcr/prototype_i386 b/usr/src/pkgdefs/SUNWarcr/prototype_i386
index 9067000c99..a9e7bcc394 100644
--- a/usr/src/pkgdefs/SUNWarcr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWarcr/prototype_i386
@@ -71,6 +71,7 @@ f none lib/amd64/llib-lelf.ln 644 root bin
f none lib/amd64/llib-lgen.ln 644 root bin
f none lib/amd64/llib-lintl.ln 644 root bin
f none lib/amd64/llib-lkstat.ln 644 root bin
+f none lib/amd64/llib-lmd.ln 644 root bin
f none lib/amd64/llib-lmd5.ln 644 root bin
f none lib/amd64/llib-lnsl.ln 644 root bin
f none lib/amd64/llib-lnvpair.ln 644 root bin
diff --git a/usr/src/pkgdefs/SUNWarcr/prototype_sparc b/usr/src/pkgdefs/SUNWarcr/prototype_sparc
index 749986b4f9..98fc3e8919 100644
--- a/usr/src/pkgdefs/SUNWarcr/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWarcr/prototype_sparc
@@ -71,6 +71,7 @@ f none lib/sparcv9/llib-lelf.ln 644 root bin
f none lib/sparcv9/llib-lgen.ln 644 root bin
f none lib/sparcv9/llib-lintl.ln 644 root bin
f none lib/sparcv9/llib-lkstat.ln 644 root bin
+f none lib/sparcv9/llib-lmd.ln 644 root bin
f none lib/sparcv9/llib-lmd5.ln 644 root bin
f none lib/sparcv9/llib-lnsl.ln 644 root bin
f none lib/sparcv9/llib-lnvpair.ln 644 root bin
diff --git a/usr/src/pkgdefs/SUNWcar.u/prototype_com b/usr/src/pkgdefs/SUNWcar.u/prototype_com
index a8fd3c808b..6c585372b4 100644
--- a/usr/src/pkgdefs/SUNWcar.u/prototype_com
+++ b/usr/src/pkgdefs/SUNWcar.u/prototype_com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -169,40 +168,40 @@ s none platform/SUNW,UltraSPARC-IIe-NetraCT-40/lib/sparcv9/libc_psr.so.1=../../.
s none platform/SUNW,UltraSPARC-IIe-NetraCT-60/lib/sparcv9/libc_psr.so.1=../../../sun4u/lib/sparcv9/libc_psr.so.1
s none platform/SUNW,UltraSPARC-IIi-Netract/lib/sparcv9/libc_psr.so.1=../../../sun4u/lib/sparcv9/libc_psr.so.1
s none platform/SUNW,Netra-CP2300/lib/sparcv9/libc_psr.so.1=../../../sun4u/lib/sparcv9/libc_psr.so.1
-f none platform/sun4u/lib/sparcv9/libmd5_psr.so.1 755 root bin
-s none platform/SUNW,Netra-T12/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Netra-T4/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Serverblade1/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Blade-100/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Blade-1000/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Blade-1500/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Blade-2500/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,A70/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V445/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V215/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Netra-CP3010/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-15000/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-480R/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V240/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V250/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V440/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-280R/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-880/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-2/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-250/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-30/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-4/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-5_10/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-60/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-80/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,UltraAX-i2/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-Enterprise-10000/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Ultra-Enterprise/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,UltraSPARC-IIe-NetraCT-40/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,UltraSPARC-IIe-NetraCT-60/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,UltraSPARC-IIi-Netract/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
-s none platform/SUNW,Netra-CP2300/lib/sparcv9/libmd5_psr.so.1=../../../sun4u/lib/sparcv9/libmd5_psr.so.1
+f none platform/sun4u/lib/sparcv9/libmd_psr.so.1 755 root bin
+s none platform/SUNW,Netra-T12/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Netra-T4/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Serverblade1/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Blade-100/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Blade-1000/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Blade-1500/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Blade-2500/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,A70/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V445/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V215/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Netra-CP3010/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-15000/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-480R/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V240/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V250/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V440/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-280R/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-880/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-2/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-250/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-30/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-4/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-5_10/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-60/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-80/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,UltraAX-i2/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-Enterprise-10000/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Ultra-Enterprise/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,UltraSPARC-IIe-NetraCT-40/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,UltraSPARC-IIe-NetraCT-60/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,UltraSPARC-IIi-Netract/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
+s none platform/SUNW,Netra-CP2300/lib/sparcv9/libmd_psr.so.1=../../../sun4u/lib/sparcv9/libmd_psr.so.1
#
# lib/libc_psr.so.1 and links to it for each sun4u platform
#
@@ -280,39 +279,39 @@ s none platform/SUNW,UltraSPARC-IIe-NetraCT-40/lib/libc_psr.so.1=../../sun4u/lib
s none platform/SUNW,UltraSPARC-IIe-NetraCT-60/lib/libc_psr.so.1=../../sun4u/lib/libc_psr.so.1
s none platform/SUNW,Netra-CP2300/lib/libc_psr.so.1=../../sun4u/lib/libc_psr.so.1
#
-# lib/libmd5_psr.so.1 and links to it for each sun4u platform
+# lib/libmd_psr.so.1 and links to it for each sun4u platform
#
-f none platform/sun4u/lib/libmd5_psr.so.1 755 root bin
-s none platform/SUNW,Ultra-2/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Ultra-250/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Ultra-30/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Ultra-4/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Ultra-5_10/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Ultra-60/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Ultra-80/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,UltraAX-i2/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Ultra-Enterprise/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Ultra-Enterprise-10000/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Serverblade1/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Blade-100/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Blade-1000/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Blade-1500/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Blade-2500/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,A70/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V445/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V215/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Netra-CP3010/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V240/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V250/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-V440/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-280R/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-15000/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-880/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Sun-Fire-480R/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Netra-T4/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Netra-T12/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,UltraSPARC-IIi-Netract/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,UltraSPARC-IIe-NetraCT-40/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,UltraSPARC-IIe-NetraCT-60/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
-s none platform/SUNW,Netra-CP2300/lib/libmd5_psr.so.1=../../sun4u/lib/libmd5_psr.so.1
+f none platform/sun4u/lib/libmd_psr.so.1 755 root bin
+s none platform/SUNW,Ultra-2/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Ultra-250/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Ultra-30/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Ultra-4/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Ultra-5_10/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Ultra-60/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Ultra-80/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,UltraAX-i2/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Ultra-Enterprise/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Ultra-Enterprise-10000/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Serverblade1/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Blade-100/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Blade-1000/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Blade-1500/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Blade-2500/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,A70/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V445/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V215/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Netra-CP3010/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V240/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V250/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-V440/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-280R/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-15000/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-880/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Sun-Fire-480R/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Netra-T4/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Netra-T12/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,UltraSPARC-IIi-Netract/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,UltraSPARC-IIe-NetraCT-40/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,UltraSPARC-IIe-NetraCT-60/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
+s none platform/SUNW,Netra-CP2300/lib/libmd_psr.so.1=../../sun4u/lib/libmd_psr.so.1
diff --git a/usr/src/pkgdefs/SUNWcar.v/prototype_com b/usr/src/pkgdefs/SUNWcar.v/prototype_com
index 348f6f5645..d39c305fb2 100644
--- a/usr/src/pkgdefs/SUNWcar.v/prototype_com
+++ b/usr/src/pkgdefs/SUNWcar.v/prototype_com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -52,6 +51,8 @@ d none platform/sun4v/lib/libc_psr 755 root bin
d none platform/sun4v/lib/sparcv9 755 root bin
v none platform/sun4v/lib/sparcv9/libc_psr.so.1 644 root bin
d none platform/sun4v/lib/sparcv9/libc_psr 755 root bin
+f none platform/sun4v/lib/libmd_psr.so.1 755 root bin
+f none platform/sun4v/lib/sparcv9/libmd_psr.so.1 755 root bin
d none etc 755 root sys
d none etc/flash 755 root sys
d none etc/flash/precreation 700 root sys
diff --git a/usr/src/pkgdefs/SUNWcsl/prototype_com b/usr/src/pkgdefs/SUNWcsl/prototype_com
index db4463ed17..cd058cbfc1 100644
--- a/usr/src/pkgdefs/SUNWcsl/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_com
@@ -163,6 +163,8 @@ f none usr/lib/libmalloc.so.1 755 root bin
s none usr/ccs/lib/libmalloc.so=../../lib/libmalloc.so.1
s none usr/lib/libmapmalloc.so=./libmapmalloc.so.1
f none usr/lib/libmapmalloc.so.1 755 root bin
+s none usr/lib/libmd.so.1=../../lib/libmd.so.1
+s none usr/lib/libmd.so=../../lib/libmd.so.1
s none usr/lib/libmd5.so.1=../../lib/libmd5.so.1
s none usr/lib/libmd5.so=../../lib/libmd5.so.1
f none usr/lib/libmenu.so.1 755 root bin
diff --git a/usr/src/pkgdefs/SUNWcsl/prototype_i386 b/usr/src/pkgdefs/SUNWcsl/prototype_i386
index d166c38401..bb41d82595 100644
--- a/usr/src/pkgdefs/SUNWcsl/prototype_i386
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_i386
@@ -173,6 +173,8 @@ f none usr/lib/amd64/liblgrp.so.1 755 root bin
s none usr/lib/amd64/liblgrp.so=liblgrp.so.1
f none usr/lib/amd64/libmalloc.so.1 755 root bin
s none usr/lib/amd64/libmalloc.so=libmalloc.so.1
+s none usr/lib/amd64/libmd.so.1=../../../lib/amd64/libmd.so.1
+s none usr/lib/amd64/libmd.so=../../../lib/amd64/libmd.so.1
s none usr/lib/amd64/libmd5.so.1=../../../lib/amd64/libmd5.so.1
s none usr/lib/amd64/libmd5.so=../../../lib/amd64/libmd5.so.1
f none usr/lib/amd64/libmenu.so.1 755 root bin
diff --git a/usr/src/pkgdefs/SUNWcsl/prototype_sparc b/usr/src/pkgdefs/SUNWcsl/prototype_sparc
index ec3a29ce8b..aff0313aa9 100644
--- a/usr/src/pkgdefs/SUNWcsl/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWcsl/prototype_sparc
@@ -166,6 +166,8 @@ f none usr/lib/sparcv9/liblgrp.so.1 755 root bin
s none usr/lib/sparcv9/liblgrp.so=liblgrp.so.1
f none usr/lib/sparcv9/libmalloc.so.1 755 root bin
s none usr/lib/sparcv9/libmalloc.so=libmalloc.so.1
+s none usr/lib/sparcv9/libmd.so.1=../../../lib/sparcv9/libmd.so.1
+s none usr/lib/sparcv9/libmd.so=../../../lib/sparcv9/libmd.so.1
s none usr/lib/sparcv9/libmd5.so.1=../../../lib/sparcv9/libmd5.so.1
s none usr/lib/sparcv9/libmd5.so=../../../lib/sparcv9/libmd5.so.1
f none usr/lib/sparcv9/libmenu.so.1 755 root bin
diff --git a/usr/src/pkgdefs/SUNWcslr/prototype_com b/usr/src/pkgdefs/SUNWcslr/prototype_com
index b02e237504..08751f4cda 100644
--- a/usr/src/pkgdefs/SUNWcslr/prototype_com
+++ b/usr/src/pkgdefs/SUNWcslr/prototype_com
@@ -98,6 +98,8 @@ f none lib/liblaadm.so.1 755 root bin
f none lib/libld.so.4 755 root bin
f none lib/liblddbg.so.4 755 root bin
f none lib/libmacadm.so.1 755 root bin
+s none lib/libmd.so=libmd.so.1
+f none lib/libmd.so.1 755 root bin
s none lib/libmd5.so=libmd5.so.1
f none lib/libmd5.so.1 755 root bin
s none lib/libmp.so=libmp.so.2
diff --git a/usr/src/pkgdefs/SUNWcslr/prototype_i386 b/usr/src/pkgdefs/SUNWcslr/prototype_i386
index 300ab68c3b..77ff9670fa 100644
--- a/usr/src/pkgdefs/SUNWcslr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWcslr/prototype_i386
@@ -95,6 +95,8 @@ s none lib/amd64/libkstat.so=libkstat.so.1
f none lib/amd64/libkstat.so.1 755 root bin
f none lib/amd64/libld.so.4 755 root bin
f none lib/amd64/liblddbg.so.4 755 root bin
+s none lib/amd64/libmd.so=libmd.so.1
+f none lib/amd64/libmd.so.1 755 root bin
s none lib/amd64/libmd5.so=libmd5.so.1
f none lib/amd64/libmd5.so.1 755 root bin
s none lib/amd64/libmp.so=libmp.so.2
diff --git a/usr/src/pkgdefs/SUNWcslr/prototype_sparc b/usr/src/pkgdefs/SUNWcslr/prototype_sparc
index 4ec7297175..4f15ae2ac0 100644
--- a/usr/src/pkgdefs/SUNWcslr/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWcslr/prototype_sparc
@@ -98,6 +98,8 @@ s none lib/sparcv9/libkstat.so=libkstat.so.1
f none lib/sparcv9/libkstat.so.1 755 root bin
f none lib/sparcv9/libld.so.4 755 root bin
f none lib/sparcv9/liblddbg.so.4 755 root bin
+s none lib/sparcv9/libmd.so=libmd.so.1
+f none lib/sparcv9/libmd.so.1 755 root bin
s none lib/sparcv9/libmd5.so=libmd5.so.1
f none lib/sparcv9/libmd5.so.1 755 root bin
s none lib/sparcv9/libmp.so=libmp.so.2
diff --git a/usr/src/pkgdefs/SUNWhea/prototype_com b/usr/src/pkgdefs/SUNWhea/prototype_com
index 5fe00a2666..dd13eff509 100644
--- a/usr/src/pkgdefs/SUNWhea/prototype_com
+++ b/usr/src/pkgdefs/SUNWhea/prototype_com
@@ -201,6 +201,7 @@ f none usr/include/locale.h 644 root bin
f none usr/include/macros.h 644 root bin
f none usr/include/maillock.h 644 root bin
f none usr/include/malloc.h 644 root bin
+f none usr/include/md4.h 644 root bin
f none usr/include/md5.h 644 root bin
f none usr/include/mdmn_changelog.h 644 root bin
f none usr/include/memory.h 644 root bin
@@ -467,6 +468,8 @@ f none usr/include/security/pkcs11t.h 644 root bin
f none usr/include/semaphore.h 644 root bin
f none usr/include/setjmp.h 644 root bin
f none usr/include/sgtty.h 644 root bin
+f none usr/include/sha1.h 644 root bin
+f none usr/include/sha2.h 644 root bin
f none usr/include/shadow.h 644 root bin
f none usr/include/siginfo.h 644 root bin
f none usr/include/signal.h 644 root bin
@@ -1014,6 +1017,8 @@ f none usr/include/sys/semaphore.h 644 root bin
f none usr/include/sys/sendfile.h 644 root bin
f none usr/include/sys/ser_sync.h 644 root bin
f none usr/include/sys/session.h 644 root bin
+f none usr/include/sys/sha1.h 644 root bin
+f none usr/include/sys/sha2.h 644 root bin
f none usr/include/sys/share.h 644 root bin
f none usr/include/sys/shm.h 644 root bin
f none usr/include/sys/shm_impl.h 644 root bin
diff --git a/usr/src/stand/lib/Makefile.targ b/usr/src/stand/lib/Makefile.targ
index 5f71e9449f..8a44eedab6 100644
--- a/usr/src/stand/lib/Makefile.targ
+++ b/usr/src/stand/lib/Makefile.targ
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,9 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
-#
+#
# ident "%Z%%M% %I% %E% SMI"
#
@@ -57,6 +56,10 @@ objs/%.o: $(CMNDIR)/%.c
$(COMPILE.c) -o $@ $<
$(POST_PROCESS_O)
+objs/%.o: $(SHA1DIR)/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
$(ROOTLIBDIR):
$(INS.dir)
diff --git a/usr/src/stand/lib/scrypt/Makefile b/usr/src/stand/lib/scrypt/Makefile
index bddb8bea66..e0175c963d 100644
--- a/usr/src/stand/lib/scrypt/Makefile
+++ b/usr/src/stand/lib/scrypt/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,18 +19,21 @@
# CDDL HEADER END
#
#
-# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
-#
+#
# ident "%Z%%M% %I% %E% SMI"
#
LIBRARY = libscrypt.a
-OBJECTS = sha1.o hmac_sha1.o des3.o des.o aes.o cbc.o
+COBJECTS = hmac_sha1.o des3.o des.o aes.o cbc.o
+SHA1_OBJS = sha1.o
+OBJECTS = $(COBJECTS) $(SHA1_OBJS)
include ../Makefile.com
CMNDIR = $(TOPDIR)/common/net/wanboot/crypt
-SRCS = $(OBJECTS:%.o=$(CMNDIR)/%.c)
+SHA1DIR = $(TOPDIR)/common/crypto/sha1
+SRCS = $(COBJECTS:%.o=$(CMNDIR)/%.c) $(SHA1_OBJS:%.o=$(SHA1DIR)/%.c)
include ../Makefile.targ
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index f735d270c7..4a9f3d19b8 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -393,11 +393,11 @@ PTY_OBJS += ptms_conf.o
SAD_OBJS += sad.o
-MD5_OBJS += md5.o
+MD5_OBJS += md5.o md5_mod.o
-SHA1_OBJS += sha1.o
+SHA1_OBJS += sha1.o sha1_mod.o
-SHA2_OBJS += sha2.o
+SHA2_OBJS += sha2.o sha2_mod.o
IPGPC_OBJS += classifierddi.o classifier.o filters.o trie.o table.o \
ba_table.o
diff --git a/usr/src/uts/common/crypto/io/md5_mod.c b/usr/src/uts/common/crypto/io/md5_mod.c
new file mode 100644
index 0000000000..bd44191ae6
--- /dev/null
+++ b/usr/src/uts/common/crypto/io/md5_mod.c
@@ -0,0 +1,1500 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * In kernel module, the md5 module is created with two modlinkages:
+ * - a modlmisc that allows consumers to directly call the entry points
+ * MD5Init, MD5Update, and MD5Final.
+ * - a modlcrypto that allows the module to register with the Kernel
+ * Cryptographic Framework (KCF) as a software provider for the MD5
+ * mechanisms.
+ */
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/modctl.h>
+#include <sys/cmn_err.h>
+#include <sys/ddi.h>
+#include <sys/crypto/common.h>
+#include <sys/crypto/spi.h>
+#include <sys/sysmacros.h>
+#include <sys/strsun.h>
+#include <sys/note.h>
+#include <sys/md5.h>
+
+extern struct mod_ops mod_miscops;
+extern struct mod_ops mod_cryptoops;
+
+/*
+ * Module linkage information for the kernel.
+ */
+
+static struct modlmisc modlmisc = {
+ &mod_miscops,
+ "MD5 Message-Digest Algorithm"
+};
+
+static struct modlcrypto modlcrypto = {
+ &mod_cryptoops,
+ "MD5 Kernel SW Provider %I%"
+};
+
+static struct modlinkage modlinkage = {
+ MODREV_1,
+ (void *)&modlmisc,
+ (void *)&modlcrypto,
+ NULL
+};
+
+/*
+ * CSPI information (entry points, provider info, etc.)
+ */
+
+typedef enum md5_mech_type {
+ MD5_MECH_INFO_TYPE, /* SUN_CKM_MD5 */
+ MD5_HMAC_MECH_INFO_TYPE, /* SUN_CKM_MD5_HMAC */
+ MD5_HMAC_GEN_MECH_INFO_TYPE /* SUN_CKM_MD5_HMAC_GENERAL */
+} md5_mech_type_t;
+
+#define MD5_DIGEST_LENGTH 16 /* MD5 digest length in bytes */
+#define MD5_HMAC_BLOCK_SIZE 64 /* MD5 block size */
+#define MD5_HMAC_MIN_KEY_LEN 8 /* MD5-HMAC min key length in bits */
+#define MD5_HMAC_MAX_KEY_LEN INT_MAX /* MD5-HMAC max key length in bits */
+#define MD5_HMAC_INTS_PER_BLOCK (MD5_HMAC_BLOCK_SIZE/sizeof (uint32_t))
+
+/*
+ * Context for MD5 mechanism.
+ */
+typedef struct md5_ctx {
+ md5_mech_type_t mc_mech_type; /* type of context */
+ MD5_CTX mc_md5_ctx; /* MD5 context */
+} md5_ctx_t;
+
+/*
+ * Context for MD5-HMAC and MD5-HMAC-GENERAL mechanisms.
+ */
+typedef struct md5_hmac_ctx {
+ md5_mech_type_t hc_mech_type; /* type of context */
+ uint32_t hc_digest_len; /* digest len in bytes */
+ MD5_CTX hc_icontext; /* inner MD5 context */
+ MD5_CTX hc_ocontext; /* outer MD5 context */
+} md5_hmac_ctx_t;
+
+/*
+ * Macros to access the MD5 or MD5-HMAC contexts from a context passed
+ * by KCF to one of the entry points.
+ */
+
+#define PROV_MD5_CTX(ctx) ((md5_ctx_t *)(ctx)->cc_provider_private)
+#define PROV_MD5_HMAC_CTX(ctx) ((md5_hmac_ctx_t *)(ctx)->cc_provider_private)
+/* to extract the digest length passed as mechanism parameter */
+
+#define PROV_MD5_GET_DIGEST_LEN(m, len) { \
+ if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \
+ (len) = (uint32_t)*((ulong_t *)mechanism->cm_param); \
+ else { \
+ ulong_t tmp_ulong; \
+ bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \
+ (len) = (uint32_t)tmp_ulong; \
+ } \
+}
+
+#define PROV_MD5_DIGEST_KEY(ctx, key, len, digest) { \
+ MD5Init(ctx); \
+ MD5Update(ctx, key, len); \
+ MD5Final(digest, ctx); \
+}
+
+/*
+ * Mechanism info structure passed to KCF during registration.
+ */
+static crypto_mech_info_t md5_mech_info_tab[] = {
+ /* MD5 */
+ {SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
+ CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
+ 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* MD5-HMAC */
+ {SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* MD5-HMAC GENERAL */
+ {SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS}
+};
+
+static void md5_provider_status(crypto_provider_handle_t, uint_t *);
+
+static crypto_control_ops_t md5_control_ops = {
+ md5_provider_status
+};
+
+static int md5_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
+ crypto_req_handle_t);
+static int md5_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int md5_digest_update(crypto_ctx_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int md5_digest_final(crypto_ctx_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int md5_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
+ crypto_req_handle_t);
+
+static crypto_digest_ops_t md5_digest_ops = {
+ md5_digest_init,
+ md5_digest,
+ md5_digest_update,
+ NULL,
+ md5_digest_final,
+ md5_digest_atomic
+};
+
+static int md5_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+static int md5_mac_update(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
+static int md5_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
+static int md5_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+static int md5_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+
+static crypto_mac_ops_t md5_mac_ops = {
+ md5_mac_init,
+ NULL,
+ md5_mac_update,
+ md5_mac_final,
+ md5_mac_atomic,
+ md5_mac_verify_atomic
+};
+
+static int md5_create_ctx_template(crypto_provider_handle_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
+ size_t *, crypto_req_handle_t);
+static int md5_free_context(crypto_ctx_t *);
+
+static crypto_ctx_ops_t md5_ctx_ops = {
+ md5_create_ctx_template,
+ md5_free_context
+};
+
+static crypto_ops_t md5_crypto_ops = {
+ &md5_control_ops,
+ &md5_digest_ops,
+ NULL,
+ &md5_mac_ops,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &md5_ctx_ops
+};
+
+static crypto_provider_info_t md5_prov_info = {
+ CRYPTO_SPI_VERSION_1,
+ "MD5 Software Provider",
+ CRYPTO_SW_PROVIDER,
+ {&modlinkage},
+ NULL,
+ &md5_crypto_ops,
+ sizeof (md5_mech_info_tab)/sizeof (crypto_mech_info_t),
+ md5_mech_info_tab
+};
+
+static crypto_kcf_provider_handle_t md5_prov_handle = NULL;
+
+int
+_init(void)
+{
+ int ret;
+
+ if ((ret = mod_install(&modlinkage)) != 0)
+ return (ret);
+
+ /*
+ * Register with KCF. If the registration fails, log an
+ * error but do not uninstall the module, since the functionality
+ * provided by misc/md5 should still be available.
+ */
+ if ((ret = crypto_register_provider(&md5_prov_info,
+ &md5_prov_handle)) != CRYPTO_SUCCESS)
+ cmn_err(CE_WARN, "md5 _init: "
+ "crypto_register_provider() failed (0x%x)", ret);
+
+ return (0);
+}
+
+int
+_fini(void)
+{
+ int ret;
+
+ /*
+ * Unregister from KCF if previous registration succeeded.
+ */
+ if (md5_prov_handle != NULL) {
+ if ((ret = crypto_unregister_provider(md5_prov_handle)) !=
+ CRYPTO_SUCCESS) {
+ cmn_err(CE_WARN, "md5 _fini: "
+ "crypto_unregister_provider() failed (0x%x)", ret);
+ return (EBUSY);
+ }
+ md5_prov_handle = NULL;
+ }
+
+ return (mod_remove(&modlinkage));
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+ return (mod_info(&modlinkage, modinfop));
+}
+
+/*
+ * KCF software provider control entry points.
+ */
+/* ARGSUSED */
+static void
+md5_provider_status(crypto_provider_handle_t provider, uint_t *status)
+{
+ *status = CRYPTO_PROVIDER_READY;
+}
+
+/*
+ * KCF software provider digest entry points.
+ */
+
+static int
+md5_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
+ crypto_req_handle_t req)
+{
+ if (mechanism->cm_type != MD5_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /*
+ * Allocate and initialize MD5 context.
+ */
+ ctx->cc_provider_private = kmem_alloc(sizeof (md5_ctx_t),
+ crypto_kmflag(req));
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ PROV_MD5_CTX(ctx)->mc_mech_type = MD5_MECH_INFO_TYPE;
+ MD5Init(&PROV_MD5_CTX(ctx)->mc_md5_ctx);
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper MD5 digest update function for uio data.
+ */
+static int
+md5_digest_update_uio(MD5_CTX *md5_ctx, crypto_data_t *data)
+{
+ off_t offset = data->cd_offset;
+ size_t length = data->cd_length;
+ uint_t vec_idx;
+ size_t cur_len;
+
+ /* we support only kernel buffer */
+ if (data->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Jump to the first iovec containing data to be
+ * digested.
+ */
+ for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt &&
+ offset >= data->cd_uio->uio_iov[vec_idx].iov_len;
+ offset -= data->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == data->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ /*
+ * Now do the digesting on the iovecs.
+ */
+ while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) {
+ cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+
+ MD5Update(md5_ctx, data->cd_uio->uio_iov[vec_idx].iov_base +
+ offset, cur_len);
+
+ length -= cur_len;
+ vec_idx++;
+ offset = 0;
+ }
+
+ if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) {
+ /*
+ * The end of the specified iovec's was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper MD5 digest final function for uio data.
+ * digest_len is the length of the desired digest. If digest_len
+ * is smaller than the default MD5 digest length, the caller
+ * must pass a scratch buffer, digest_scratch, which must
+ * be at least MD5_DIGEST_LENGTH bytes.
+ */
+static int
+md5_digest_final_uio(MD5_CTX *md5_ctx, crypto_data_t *digest,
+ ulong_t digest_len, uchar_t *digest_scratch)
+{
+ off_t offset = digest->cd_offset;
+ uint_t vec_idx;
+
+ /* we support only kernel buffer */
+ if (digest->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Jump to the first iovec containing ptr to the digest to
+ * be returned.
+ */
+ for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len &&
+ vec_idx < digest->cd_uio->uio_iovcnt;
+ offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == digest->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is
+ * larger than the total size of the buffers
+ * it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ if (offset + digest_len <=
+ digest->cd_uio->uio_iov[vec_idx].iov_len) {
+ /*
+ * The computed MD5 digest will fit in the current
+ * iovec.
+ */
+ if (digest_len != MD5_DIGEST_LENGTH) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ MD5Final(digest_scratch, md5_ctx);
+ bcopy(digest_scratch, (uchar_t *)digest->
+ cd_uio->uio_iov[vec_idx].iov_base + offset,
+ digest_len);
+ } else {
+ MD5Final((uchar_t *)digest->
+ cd_uio->uio_iov[vec_idx].iov_base + offset,
+ md5_ctx);
+ }
+ } else {
+ /*
+ * The computed digest will be crossing one or more iovec's.
+ * This is bad performance-wise but we need to support it.
+ * Allocate a small scratch buffer on the stack and
+ * copy it piece meal to the specified digest iovec's.
+ */
+ uchar_t digest_tmp[MD5_DIGEST_LENGTH];
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ MD5Final(digest_tmp, md5_ctx);
+
+ while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) {
+ cur_len = MIN(digest->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+ bcopy(digest_tmp + scratch_offset,
+ digest->cd_uio->uio_iov[vec_idx].iov_base + offset,
+ cur_len);
+
+ length -= cur_len;
+ vec_idx++;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+
+ if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) {
+ /*
+ * The end of the specified iovec's was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it
+ * provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper MD5 digest update for mblk's.
+ */
+static int
+md5_digest_update_mblk(MD5_CTX *md5_ctx, crypto_data_t *data)
+{
+ off_t offset = data->cd_offset;
+ size_t length = data->cd_length;
+ mblk_t *mp;
+ size_t cur_len;
+
+ /*
+ * Jump to the first mblk_t containing data to be digested.
+ */
+ for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ /*
+ * Now do the digesting on the mblk chain.
+ */
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ MD5Update(md5_ctx, mp->b_rptr + offset, cur_len);
+ length -= cur_len;
+ offset = 0;
+ mp = mp->b_cont;
+ }
+
+ if (mp == NULL && length > 0) {
+ /*
+ * The end of the mblk was reached but the length requested
+ * could not be processed, i.e. The caller requested
+ * to digest more data than it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper MD5 digest final for mblk's.
+ * digest_len is the length of the desired digest. If digest_len
+ * is smaller than the default MD5 digest length, the caller
+ * must pass a scratch buffer, digest_scratch, which must
+ * be at least MD5_DIGEST_LENGTH bytes.
+ */
+static int
+md5_digest_final_mblk(MD5_CTX *md5_ctx, crypto_data_t *digest,
+ ulong_t digest_len, uchar_t *digest_scratch)
+{
+ off_t offset = digest->cd_offset;
+ mblk_t *mp;
+
+ /*
+ * Jump to the first mblk_t that will be used to store the digest.
+ */
+ for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ if (offset + digest_len <= MBLKL(mp)) {
+ /*
+ * The computed MD5 digest will fit in the current mblk.
+ * Do the MD5Final() in-place.
+ */
+ if (digest_len != MD5_DIGEST_LENGTH) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ MD5Final(digest_scratch, md5_ctx);
+ bcopy(digest_scratch, mp->b_rptr + offset, digest_len);
+ } else {
+ MD5Final(mp->b_rptr + offset, md5_ctx);
+ }
+ } else {
+ /*
+ * The computed digest will be crossing one or more mblk's.
+ * This is bad performance-wise but we need to support it.
+ * Allocate a small scratch buffer on the stack and
+ * copy it piece meal to the specified digest iovec's.
+ */
+ uchar_t digest_tmp[MD5_DIGEST_LENGTH];
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ MD5Final(digest_tmp, md5_ctx);
+
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ bcopy(digest_tmp + scratch_offset,
+ mp->b_rptr + offset, cur_len);
+
+ length -= cur_len;
+ mp = mp->b_cont;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+
+ if (mp == NULL && length > 0) {
+ /*
+ * The end of the specified mblk was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it
+ * provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/* ARGSUSED */
+static int
+md5_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((digest->cd_length == 0) ||
+ (digest->cd_length < MD5_DIGEST_LENGTH)) {
+ digest->cd_length = MD5_DIGEST_LENGTH;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do the MD5 update on the specified input data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ MD5Update(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_update_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_update_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret != CRYPTO_SUCCESS) {
+ /* the update failed, free context and bail */
+ kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
+ ctx->cc_provider_private = NULL;
+ digest->cd_length = 0;
+ return (ret);
+ }
+
+ /*
+ * Do an MD5 final, must be done separately since the digest
+ * type can be different than the input data type.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ MD5Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &PROV_MD5_CTX(ctx)->mc_md5_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_final_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ digest, MD5_DIGEST_LENGTH, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_final_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ digest, MD5_DIGEST_LENGTH, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ /* all done, free context and return */
+
+ if (ret == CRYPTO_SUCCESS) {
+ digest->cd_length = MD5_DIGEST_LENGTH;
+ } else {
+ digest->cd_length = 0;
+ }
+
+ kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
+ ctx->cc_provider_private = NULL;
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+md5_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * Do the MD5 update on the specified input data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ MD5Update(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_update_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_update_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+md5_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((digest->cd_length == 0) ||
+ (digest->cd_length < MD5_DIGEST_LENGTH)) {
+ digest->cd_length = MD5_DIGEST_LENGTH;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do an MD5 final.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ MD5Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &PROV_MD5_CTX(ctx)->mc_md5_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_final_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ digest, MD5_DIGEST_LENGTH, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_final_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
+ digest, MD5_DIGEST_LENGTH, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ /* all done, free context and return */
+
+ if (ret == CRYPTO_SUCCESS) {
+ digest->cd_length = MD5_DIGEST_LENGTH;
+ } else {
+ digest->cd_length = 0;
+ }
+
+ kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
+ ctx->cc_provider_private = NULL;
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+md5_digest_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_data_t *data, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ MD5_CTX md5_ctx;
+
+ if (mechanism->cm_type != MD5_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /*
+ * Do the MD5 init.
+ */
+ MD5Init(&md5_ctx);
+
+ /*
+ * Do the MD5 update on the specified input data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ MD5Update(&md5_ctx, data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_update_uio(&md5_ctx, data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_update_mblk(&md5_ctx, data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret != CRYPTO_SUCCESS) {
+ /* the update failed, bail */
+ digest->cd_length = 0;
+ return (ret);
+ }
+
+ /*
+ * Do an MD5 final, must be done separately since the digest
+ * type can be different than the input data type.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ MD5Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &md5_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_final_uio(&md5_ctx, digest,
+ MD5_DIGEST_LENGTH, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_final_mblk(&md5_ctx, digest,
+ MD5_DIGEST_LENGTH, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS) {
+ digest->cd_length = MD5_DIGEST_LENGTH;
+ } else {
+ digest->cd_length = 0;
+ }
+
+ return (ret);
+}
+
+/*
+ * KCF software provider mac entry points.
+ *
+ * MD5 HMAC is: MD5(key XOR opad, MD5(key XOR ipad, text))
+ *
+ * Init:
+ * The initialization routine initializes what we denote
+ * as the inner and outer contexts by doing
+ * - for inner context: MD5(key XOR ipad)
+ * - for outer context: MD5(key XOR opad)
+ *
+ * Update:
+ * Each subsequent MD5 HMAC update will result in an
+ * update of the inner context with the specified data.
+ *
+ * Final:
+ * The MD5 HMAC final will do a MD5 final operation on the
+ * inner context, and the resulting digest will be used
+ * as the data for an update on the outer context. Last
+ * but not least, an MD5 final on the outer context will
+ * be performed to obtain the MD5 HMAC digest to return
+ * to the user.
+ */
+
+/*
+ * Initialize a MD5-HMAC context.
+ */
+static void
+md5_mac_init_ctx(md5_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
+{
+ uint32_t ipad[MD5_HMAC_INTS_PER_BLOCK];
+ uint32_t opad[MD5_HMAC_INTS_PER_BLOCK];
+ uint_t i;
+
+ bzero(ipad, MD5_HMAC_BLOCK_SIZE);
+ bzero(opad, MD5_HMAC_BLOCK_SIZE);
+
+ bcopy(keyval, ipad, length_in_bytes);
+ bcopy(keyval, opad, length_in_bytes);
+
+ /* XOR key with ipad (0x36) and opad (0x5c) */
+ for (i = 0; i < MD5_HMAC_INTS_PER_BLOCK; i++) {
+ ipad[i] ^= 0x36363636;
+ opad[i] ^= 0x5c5c5c5c;
+ }
+
+ /* perform MD5 on ipad */
+ MD5Init(&ctx->hc_icontext);
+ MD5Update(&ctx->hc_icontext, ipad, MD5_HMAC_BLOCK_SIZE);
+
+ /* perform MD5 on opad */
+ MD5Init(&ctx->hc_ocontext);
+ MD5Update(&ctx->hc_ocontext, opad, MD5_HMAC_BLOCK_SIZE);
+}
+
+/*
+ * Initializes a multi-part MAC operation.
+ */
+static int
+md5_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
+ mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ ctx->cc_provider_private = kmem_alloc(sizeof (md5_hmac_ctx_t),
+ crypto_kmflag(req));
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, PROV_MD5_HMAC_CTX(ctx),
+ sizeof (md5_hmac_ctx_t));
+ } else {
+ /* no context template, compute context */
+ if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
+ uchar_t digested_key[MD5_DIGEST_LENGTH];
+ md5_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
+
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_MD5_DIGEST_KEY(&hmac_ctx->hc_icontext,
+ key->ck_data, keylen_in_bytes, digested_key);
+ md5_mac_init_ctx(PROV_MD5_HMAC_CTX(ctx),
+ digested_key, MD5_DIGEST_LENGTH);
+ } else {
+ md5_mac_init_ctx(PROV_MD5_HMAC_CTX(ctx),
+ key->ck_data, keylen_in_bytes);
+ }
+ }
+
+ /*
+ * Get the mechanism parameters, if applicable.
+ */
+ PROV_MD5_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
+ if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t))
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ PROV_MD5_GET_DIGEST_LEN(mechanism,
+ PROV_MD5_HMAC_CTX(ctx)->hc_digest_len);
+ if (PROV_MD5_HMAC_CTX(ctx)->hc_digest_len >
+ MD5_DIGEST_LENGTH)
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ }
+
+ if (ret != CRYPTO_SUCCESS) {
+ bzero(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
+ kmem_free(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
+ ctx->cc_provider_private = NULL;
+ }
+
+ return (ret);
+}
+
+
+/* ARGSUSED */
+static int
+md5_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * Do an MD5 update of the inner context using the specified
+ * data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ MD5Update(&PROV_MD5_HMAC_CTX(ctx)->hc_icontext,
+ data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_update_uio(
+ &PROV_MD5_HMAC_CTX(ctx)->hc_icontext, data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_update_mblk(
+ &PROV_MD5_HMAC_CTX(ctx)->hc_icontext, data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+md5_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[MD5_DIGEST_LENGTH];
+ uint32_t digest_len = MD5_DIGEST_LENGTH;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ if (PROV_MD5_HMAC_CTX(ctx)->hc_mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE)
+ digest_len = PROV_MD5_HMAC_CTX(ctx)->hc_digest_len;
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
+ mac->cd_length = digest_len;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do an MD5 final on the inner context.
+ */
+ MD5Final(digest, &PROV_MD5_HMAC_CTX(ctx)->hc_icontext);
+
+ /*
+ * Do an MD5 update on the outer context, feeding the inner
+ * digest as data.
+ */
+ MD5Update(&PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, digest,
+ MD5_DIGEST_LENGTH);
+
+ /*
+ * Do an MD5 final on the outer context, storing the computing
+ * digest in the users buffer.
+ */
+ switch (mac->cd_format) {
+ case CRYPTO_DATA_RAW:
+ if (digest_len != MD5_DIGEST_LENGTH) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ MD5Final(digest,
+ &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext);
+ bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len);
+ } else {
+ MD5Final((unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset,
+ &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext);
+ }
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_final_uio(
+ &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_final_mblk(
+ &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS) {
+ mac->cd_length = digest_len;
+ } else {
+ mac->cd_length = 0;
+ }
+
+ bzero(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
+ kmem_free(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
+ ctx->cc_provider_private = NULL;
+
+ return (ret);
+}
+
+#define MD5_MAC_UPDATE(data, ctx, ret) { \
+ switch (data->cd_format) { \
+ case CRYPTO_DATA_RAW: \
+ MD5Update(&(ctx).hc_icontext, \
+ data->cd_raw.iov_base + data->cd_offset, \
+ data->cd_length); \
+ break; \
+ case CRYPTO_DATA_UIO: \
+ ret = md5_digest_update_uio(&(ctx).hc_icontext, data); \
+ break; \
+ case CRYPTO_DATA_MBLK: \
+ ret = md5_digest_update_mblk(&(ctx).hc_icontext, \
+ data); \
+ break; \
+ default: \
+ ret = CRYPTO_ARGUMENTS_BAD; \
+ } \
+}
+
+
+/* ARGSUSED */
+static int
+md5_mac_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
+ crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[MD5_DIGEST_LENGTH];
+ md5_hmac_ctx_t md5_hmac_ctx;
+ uint32_t digest_len = MD5_DIGEST_LENGTH;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
+ mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, &md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
+ } else {
+ /* no context template, compute context */
+ if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_MD5_DIGEST_KEY(&md5_hmac_ctx.hc_icontext,
+ key->ck_data, keylen_in_bytes, digest);
+ md5_mac_init_ctx(&md5_hmac_ctx, digest,
+ MD5_DIGEST_LENGTH);
+ } else {
+ md5_mac_init_ctx(&md5_hmac_ctx, key->ck_data,
+ keylen_in_bytes);
+ }
+ }
+
+ /*
+ * Get the mechanism parameters, if applicable.
+ */
+ if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t)) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ PROV_MD5_GET_DIGEST_LEN(mechanism, digest_len);
+ if (digest_len > MD5_DIGEST_LENGTH) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ }
+
+ /* do an MD5 update of the inner context using the specified data */
+ MD5_MAC_UPDATE(data, md5_hmac_ctx, ret);
+ if (ret != CRYPTO_SUCCESS)
+ /* the update failed, free context and bail */
+ goto bail;
+
+ /* do an MD5 final on the inner context */
+ MD5Final(digest, &md5_hmac_ctx.hc_icontext);
+
+ /*
+ * Do an MD5 update on the outer context, feeding the inner
+ * digest as data.
+ */
+ MD5Update(&md5_hmac_ctx.hc_ocontext, digest, MD5_DIGEST_LENGTH);
+
+ /*
+ * Do an MD5 final on the outer context, storing the computed
+ * digest in the users buffer.
+ */
+ switch (mac->cd_format) {
+ case CRYPTO_DATA_RAW:
+ if (digest_len != MD5_DIGEST_LENGTH) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ MD5Final(digest, &md5_hmac_ctx.hc_ocontext);
+ bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len);
+ } else {
+ MD5Final((unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, &md5_hmac_ctx.hc_ocontext);
+ }
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = md5_digest_final_uio(&md5_hmac_ctx.hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = md5_digest_final_mblk(&md5_hmac_ctx.hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS) {
+ mac->cd_length = digest_len;
+ } else {
+ mac->cd_length = 0;
+ }
+ /* Extra paranoia: zeroizing the local context on the stack */
+ bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
+
+ return (ret);
+bail:
+ bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
+ mac->cd_length = 0;
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+md5_mac_verify_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
+ crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[MD5_DIGEST_LENGTH];
+ md5_hmac_ctx_t md5_hmac_ctx;
+ uint32_t digest_len = MD5_DIGEST_LENGTH;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
+ mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, &md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
+ } else {
+ /* no context template, compute context */
+ if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_MD5_DIGEST_KEY(&md5_hmac_ctx.hc_icontext,
+ key->ck_data, keylen_in_bytes, digest);
+ md5_mac_init_ctx(&md5_hmac_ctx, digest,
+ MD5_DIGEST_LENGTH);
+ } else {
+ md5_mac_init_ctx(&md5_hmac_ctx, key->ck_data,
+ keylen_in_bytes);
+ }
+ }
+
+ /*
+ * Get the mechanism parameters, if applicable.
+ */
+ if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t)) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ PROV_MD5_GET_DIGEST_LEN(mechanism, digest_len);
+ if (digest_len > MD5_DIGEST_LENGTH) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ }
+
+ if (mac->cd_length != digest_len) {
+ ret = CRYPTO_INVALID_MAC;
+ goto bail;
+ }
+
+ /* do an MD5 update of the inner context using the specified data */
+ MD5_MAC_UPDATE(data, md5_hmac_ctx, ret);
+ if (ret != CRYPTO_SUCCESS)
+ /* the update failed, free context and bail */
+ goto bail;
+
+ /* do an MD5 final on the inner context */
+ MD5Final(digest, &md5_hmac_ctx.hc_icontext);
+
+ /*
+ * Do an MD5 update on the outer context, feeding the inner
+ * digest as data.
+ */
+ MD5Update(&md5_hmac_ctx.hc_ocontext, digest, MD5_DIGEST_LENGTH);
+
+ /*
+ * Do an MD5 final on the outer context, storing the computed
+ * digest in the local digest buffer.
+ */
+ MD5Final(digest, &md5_hmac_ctx.hc_ocontext);
+
+ /*
+ * Compare the computed digest against the expected digest passed
+ * as argument.
+ */
+ switch (mac->cd_format) {
+
+ case CRYPTO_DATA_RAW:
+ if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len) != 0)
+ ret = CRYPTO_INVALID_MAC;
+ break;
+
+ case CRYPTO_DATA_UIO: {
+ off_t offset = mac->cd_offset;
+ uint_t vec_idx;
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ /* we support only kernel buffer */
+ if (mac->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /* jump to the first iovec containing the expected digest */
+ for (vec_idx = 0;
+ offset >= mac->cd_uio->uio_iov[vec_idx].iov_len &&
+ vec_idx < mac->cd_uio->uio_iovcnt;
+ offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == mac->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is
+ * larger than the total size of the buffers
+ * it provided.
+ */
+ ret = CRYPTO_DATA_LEN_RANGE;
+ break;
+ }
+
+ /* do the comparison of computed digest vs specified one */
+ while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) {
+ cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+
+ if (bcmp(digest + scratch_offset,
+ mac->cd_uio->uio_iov[vec_idx].iov_base + offset,
+ cur_len) != 0) {
+ ret = CRYPTO_INVALID_MAC;
+ break;
+ }
+
+ length -= cur_len;
+ vec_idx++;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+ break;
+ }
+
+ case CRYPTO_DATA_MBLK: {
+ off_t offset = mac->cd_offset;
+ mblk_t *mp;
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ /* jump to the first mblk_t containing the expected digest */
+ for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than
+ * the total size of the buffers it provided.
+ */
+ ret = CRYPTO_DATA_LEN_RANGE;
+ break;
+ }
+
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ if (bcmp(digest + scratch_offset,
+ mp->b_rptr + offset, cur_len) != 0) {
+ ret = CRYPTO_INVALID_MAC;
+ break;
+ }
+
+ length -= cur_len;
+ mp = mp->b_cont;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+ break;
+ }
+
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
+ return (ret);
+bail:
+ bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
+ mac->cd_length = 0;
+ return (ret);
+}
+
+/*
+ * KCF software provider context management entry points.
+ */
+
+/* ARGSUSED */
+static int
+md5_create_ctx_template(crypto_provider_handle_t provider,
+ crypto_mechanism_t *mechanism, crypto_key_t *key,
+ crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
+ crypto_req_handle_t req)
+{
+ md5_hmac_ctx_t *md5_hmac_ctx_tmpl;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ if ((mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE) &&
+ (mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE))
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Allocate and initialize MD5 context.
+ */
+ md5_hmac_ctx_tmpl = kmem_alloc(sizeof (md5_hmac_ctx_t),
+ crypto_kmflag(req));
+ if (md5_hmac_ctx_tmpl == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
+ uchar_t digested_key[MD5_DIGEST_LENGTH];
+
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_MD5_DIGEST_KEY(&md5_hmac_ctx_tmpl->hc_icontext,
+ key->ck_data, keylen_in_bytes, digested_key);
+ md5_mac_init_ctx(md5_hmac_ctx_tmpl, digested_key,
+ MD5_DIGEST_LENGTH);
+ } else {
+ md5_mac_init_ctx(md5_hmac_ctx_tmpl, key->ck_data,
+ keylen_in_bytes);
+ }
+
+ md5_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
+ *ctx_template = (crypto_spi_ctx_template_t)md5_hmac_ctx_tmpl;
+ *ctx_template_size = sizeof (md5_hmac_ctx_t);
+
+ return (CRYPTO_SUCCESS);
+}
+
+static int
+md5_free_context(crypto_ctx_t *ctx)
+{
+ uint_t ctx_len;
+ md5_mech_type_t mech_type;
+
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_SUCCESS);
+
+ /*
+ * We have to free either MD5 or MD5-HMAC contexts, which
+ * have different lengths.
+ */
+
+ mech_type = PROV_MD5_CTX(ctx)->mc_mech_type;
+ if (mech_type == MD5_MECH_INFO_TYPE)
+ ctx_len = sizeof (md5_ctx_t);
+ else {
+ ASSERT(mech_type == MD5_HMAC_MECH_INFO_TYPE ||
+ mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE);
+ ctx_len = sizeof (md5_hmac_ctx_t);
+ }
+
+ bzero(ctx->cc_provider_private, ctx_len);
+ kmem_free(ctx->cc_provider_private, ctx_len);
+ ctx->cc_provider_private = NULL;
+
+ return (CRYPTO_SUCCESS);
+}
diff --git a/usr/src/uts/common/crypto/io/sha1_mod.c b/usr/src/uts/common/crypto/io/sha1_mod.c
new file mode 100644
index 0000000000..11240951d2
--- /dev/null
+++ b/usr/src/uts/common/crypto/io/sha1_mod.c
@@ -0,0 +1,1471 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/modctl.h>
+#include <sys/cmn_err.h>
+#include <sys/note.h>
+#include <sys/crypto/common.h>
+#include <sys/crypto/spi.h>
+#include <sys/strsun.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+
+#include <sys/sha1.h>
+
+/*
+ * The sha1 module is created with two modlinkages:
+ * - a modlmisc that allows consumers to directly call the entry points
+ * SHA1Init, SHA1Update, and SHA1Final.
+ * - a modlcrypto that allows the module to register with the Kernel
+ * Cryptographic Framework (KCF) as a software provider for the SHA1
+ * mechanisms.
+ */
+
+static struct modlmisc modlmisc = {
+ &mod_miscops,
+ "SHA1 Message-Digest Algorithm"
+};
+
+static struct modlcrypto modlcrypto = {
+ &mod_cryptoops,
+ "SHA1 Kernel SW Provider 1.1"
+};
+
+static struct modlinkage modlinkage = {
+ MODREV_1, &modlmisc, &modlcrypto, NULL
+};
+
+/*
+ * CSPI information (entry points, provider info, etc.)
+ */
+
+typedef enum sha1_mech_type {
+ SHA1_MECH_INFO_TYPE, /* SUN_CKM_SHA1 */
+ SHA1_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA1_HMAC */
+ SHA1_HMAC_GEN_MECH_INFO_TYPE /* SUN_CKM_SHA1_HMAC_GENERAL */
+} sha1_mech_type_t;
+
+#define SHA1_DIGEST_LENGTH 20 /* SHA1 digest length in bytes */
+#define SHA1_HMAC_BLOCK_SIZE 64 /* SHA1-HMAC block size */
+#define SHA1_HMAC_MIN_KEY_LEN 8 /* SHA1-HMAC min key length in bits */
+#define SHA1_HMAC_MAX_KEY_LEN INT_MAX /* SHA1-HMAC max key length in bits */
+#define SHA1_HMAC_INTS_PER_BLOCK (SHA1_HMAC_BLOCK_SIZE/sizeof (uint32_t))
+
+/*
+ * Context for SHA1 mechanism.
+ */
+typedef struct sha1_ctx {
+ sha1_mech_type_t sc_mech_type; /* type of context */
+ SHA1_CTX sc_sha1_ctx; /* SHA1 context */
+} sha1_ctx_t;
+
+/*
+ * Context for SHA1-HMAC and SHA1-HMAC-GENERAL mechanisms.
+ */
+typedef struct sha1_hmac_ctx {
+ sha1_mech_type_t hc_mech_type; /* type of context */
+ uint32_t hc_digest_len; /* digest len in bytes */
+ SHA1_CTX hc_icontext; /* inner SHA1 context */
+ SHA1_CTX hc_ocontext; /* outer SHA1 context */
+} sha1_hmac_ctx_t;
+
+/*
+ * Macros to access the SHA1 or SHA1-HMAC contexts from a context passed
+ * by KCF to one of the entry points.
+ */
+
+#define PROV_SHA1_CTX(ctx) ((sha1_ctx_t *)(ctx)->cc_provider_private)
+#define PROV_SHA1_HMAC_CTX(ctx) ((sha1_hmac_ctx_t *)(ctx)->cc_provider_private)
+
+/* to extract the digest length passed as mechanism parameter */
+#define PROV_SHA1_GET_DIGEST_LEN(m, len) { \
+ if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \
+ (len) = (uint32_t)*((ulong_t *)mechanism->cm_param); \
+ else { \
+ ulong_t tmp_ulong; \
+ bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \
+ (len) = (uint32_t)tmp_ulong; \
+ } \
+}
+
+#define PROV_SHA1_DIGEST_KEY(ctx, key, len, digest) { \
+ SHA1Init(ctx); \
+ SHA1Update(ctx, key, len); \
+ SHA1Final(digest, ctx); \
+}
+
+/*
+ * Mechanism info structure passed to KCF during registration.
+ */
+static crypto_mech_info_t sha1_mech_info_tab[] = {
+ /* SHA1 */
+ {SUN_CKM_SHA1, SHA1_MECH_INFO_TYPE,
+ CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
+ 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA1-HMAC */
+ {SUN_CKM_SHA1_HMAC, SHA1_HMAC_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA1-HMAC GENERAL */
+ {SUN_CKM_SHA1_HMAC_GENERAL, SHA1_HMAC_GEN_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ SHA1_HMAC_MIN_KEY_LEN, SHA1_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS}
+};
+
+static void sha1_provider_status(crypto_provider_handle_t, uint_t *);
+
+static crypto_control_ops_t sha1_control_ops = {
+ sha1_provider_status
+};
+
+static int sha1_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
+ crypto_req_handle_t);
+static int sha1_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int sha1_digest_update(crypto_ctx_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int sha1_digest_final(crypto_ctx_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int sha1_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
+ crypto_req_handle_t);
+
+static crypto_digest_ops_t sha1_digest_ops = {
+ sha1_digest_init,
+ sha1_digest,
+ sha1_digest_update,
+ NULL,
+ sha1_digest_final,
+ sha1_digest_atomic
+};
+
+static int sha1_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+static int sha1_mac_update(crypto_ctx_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int sha1_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
+static int sha1_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+static int sha1_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+
+static crypto_mac_ops_t sha1_mac_ops = {
+ sha1_mac_init,
+ NULL,
+ sha1_mac_update,
+ sha1_mac_final,
+ sha1_mac_atomic,
+ sha1_mac_verify_atomic
+};
+
+static int sha1_create_ctx_template(crypto_provider_handle_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
+ size_t *, crypto_req_handle_t);
+static int sha1_free_context(crypto_ctx_t *);
+
+static crypto_ctx_ops_t sha1_ctx_ops = {
+ sha1_create_ctx_template,
+ sha1_free_context
+};
+
+static crypto_ops_t sha1_crypto_ops = {
+ &sha1_control_ops,
+ &sha1_digest_ops,
+ NULL,
+ &sha1_mac_ops,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &sha1_ctx_ops
+};
+
+static crypto_provider_info_t sha1_prov_info = {
+ CRYPTO_SPI_VERSION_1,
+ "SHA1 Software Provider",
+ CRYPTO_SW_PROVIDER,
+ {&modlinkage},
+ NULL,
+ &sha1_crypto_ops,
+ sizeof (sha1_mech_info_tab)/sizeof (crypto_mech_info_t),
+ sha1_mech_info_tab
+};
+
+static crypto_kcf_provider_handle_t sha1_prov_handle = NULL;
+
+int
+_init()
+{
+ int ret;
+
+ if ((ret = mod_install(&modlinkage)) != 0)
+ return (ret);
+
+ /*
+ * Register with KCF. If the registration fails, log an
+ * error but do not uninstall the module, since the functionality
+ * provided by misc/sha1 should still be available.
+ */
+ if ((ret = crypto_register_provider(&sha1_prov_info,
+ &sha1_prov_handle)) != CRYPTO_SUCCESS)
+ cmn_err(CE_WARN, "sha1 _init: "
+ "crypto_register_provider() failed (0x%x)", ret);
+
+ return (0);
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+ return (mod_info(&modlinkage, modinfop));
+}
+
+/*
+ * KCF software provider control entry points.
+ */
+/* ARGSUSED */
+static void
+sha1_provider_status(crypto_provider_handle_t provider, uint_t *status)
+{
+ *status = CRYPTO_PROVIDER_READY;
+}
+
+/*
+ * KCF software provider digest entry points.
+ */
+
+static int
+sha1_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
+ crypto_req_handle_t req)
+{
+ if (mechanism->cm_type != SHA1_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /*
+ * Allocate and initialize SHA1 context.
+ */
+ ctx->cc_provider_private = kmem_alloc(sizeof (sha1_ctx_t),
+ crypto_kmflag(req));
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ PROV_SHA1_CTX(ctx)->sc_mech_type = SHA1_MECH_INFO_TYPE;
+ SHA1Init(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx);
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper SHA1 digest update function for uio data.
+ */
+static int
+sha1_digest_update_uio(SHA1_CTX *sha1_ctx, crypto_data_t *data)
+{
+ off_t offset = data->cd_offset;
+ size_t length = data->cd_length;
+ uint_t vec_idx;
+ size_t cur_len;
+
+ /* we support only kernel buffer */
+ if (data->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Jump to the first iovec containing data to be
+ * digested.
+ */
+ for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt &&
+ offset >= data->cd_uio->uio_iov[vec_idx].iov_len;
+ offset -= data->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == data->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ /*
+ * Now do the digesting on the iovecs.
+ */
+ while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) {
+ cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+
+ SHA1Update(sha1_ctx,
+ (uint8_t *)data->cd_uio->uio_iov[vec_idx].iov_base + offset,
+ cur_len);
+
+ length -= cur_len;
+ vec_idx++;
+ offset = 0;
+ }
+
+ if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) {
+ /*
+ * The end of the specified iovec's was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper SHA1 digest final function for uio data.
+ * digest_len is the length of the desired digest. If digest_len
+ * is smaller than the default SHA1 digest length, the caller
+ * must pass a scratch buffer, digest_scratch, which must
+ * be at least SHA1_DIGEST_LENGTH bytes.
+ */
+static int
+sha1_digest_final_uio(SHA1_CTX *sha1_ctx, crypto_data_t *digest,
+ ulong_t digest_len, uchar_t *digest_scratch)
+{
+ off_t offset = digest->cd_offset;
+ uint_t vec_idx;
+
+ /* we support only kernel buffer */
+ if (digest->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Jump to the first iovec containing ptr to the digest to
+ * be returned.
+ */
+ for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len &&
+ vec_idx < digest->cd_uio->uio_iovcnt;
+ offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == digest->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is
+ * larger than the total size of the buffers
+ * it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ if (offset + digest_len <=
+ digest->cd_uio->uio_iov[vec_idx].iov_len) {
+ /*
+ * The computed SHA1 digest will fit in the current
+ * iovec.
+ */
+ if (digest_len != SHA1_DIGEST_LENGTH) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ SHA1Final(digest_scratch, sha1_ctx);
+ bcopy(digest_scratch, (uchar_t *)digest->
+ cd_uio->uio_iov[vec_idx].iov_base + offset,
+ digest_len);
+ } else {
+ SHA1Final((uchar_t *)digest->
+ cd_uio->uio_iov[vec_idx].iov_base + offset,
+ sha1_ctx);
+ }
+ } else {
+ /*
+ * The computed digest will be crossing one or more iovec's.
+ * This is bad performance-wise but we need to support it.
+ * Allocate a small scratch buffer on the stack and
+ * copy it piece meal to the specified digest iovec's.
+ */
+ uchar_t digest_tmp[SHA1_DIGEST_LENGTH];
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ SHA1Final(digest_tmp, sha1_ctx);
+
+ while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) {
+ cur_len = MIN(digest->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+ bcopy(digest_tmp + scratch_offset,
+ digest->cd_uio->uio_iov[vec_idx].iov_base + offset,
+ cur_len);
+
+ length -= cur_len;
+ vec_idx++;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+
+ if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) {
+ /*
+ * The end of the specified iovec's was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it
+ * provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper SHA1 digest update for mblk's.
+ */
+static int
+sha1_digest_update_mblk(SHA1_CTX *sha1_ctx, crypto_data_t *data)
+{
+ off_t offset = data->cd_offset;
+ size_t length = data->cd_length;
+ mblk_t *mp;
+ size_t cur_len;
+
+ /*
+ * Jump to the first mblk_t containing data to be digested.
+ */
+ for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ /*
+ * Now do the digesting on the mblk chain.
+ */
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ SHA1Update(sha1_ctx, mp->b_rptr + offset, cur_len);
+ length -= cur_len;
+ offset = 0;
+ mp = mp->b_cont;
+ }
+
+ if (mp == NULL && length > 0) {
+ /*
+ * The end of the mblk was reached but the length requested
+ * could not be processed, i.e. The caller requested
+ * to digest more data than it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper SHA1 digest final for mblk's.
+ * digest_len is the length of the desired digest. If digest_len
+ * is smaller than the default SHA1 digest length, the caller
+ * must pass a scratch buffer, digest_scratch, which must
+ * be at least SHA1_DIGEST_LENGTH bytes.
+ */
+static int
+sha1_digest_final_mblk(SHA1_CTX *sha1_ctx, crypto_data_t *digest,
+ ulong_t digest_len, uchar_t *digest_scratch)
+{
+ off_t offset = digest->cd_offset;
+ mblk_t *mp;
+
+ /*
+ * Jump to the first mblk_t that will be used to store the digest.
+ */
+ for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ if (offset + digest_len <= MBLKL(mp)) {
+ /*
+ * The computed SHA1 digest will fit in the current mblk.
+ * Do the SHA1Final() in-place.
+ */
+ if (digest_len != SHA1_DIGEST_LENGTH) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ SHA1Final(digest_scratch, sha1_ctx);
+ bcopy(digest_scratch, mp->b_rptr + offset, digest_len);
+ } else {
+ SHA1Final(mp->b_rptr + offset, sha1_ctx);
+ }
+ } else {
+ /*
+ * The computed digest will be crossing one or more mblk's.
+ * This is bad performance-wise but we need to support it.
+ * Allocate a small scratch buffer on the stack and
+ * copy it piece meal to the specified digest iovec's.
+ */
+ uchar_t digest_tmp[SHA1_DIGEST_LENGTH];
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ SHA1Final(digest_tmp, sha1_ctx);
+
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ bcopy(digest_tmp + scratch_offset,
+ mp->b_rptr + offset, cur_len);
+
+ length -= cur_len;
+ mp = mp->b_cont;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+
+ if (mp == NULL && length > 0) {
+ /*
+ * The end of the specified mblk was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it
+ * provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/* ARGSUSED */
+static int
+sha1_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((digest->cd_length == 0) ||
+ (digest->cd_length < SHA1_DIGEST_LENGTH)) {
+ digest->cd_length = SHA1_DIGEST_LENGTH;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do the SHA1 update on the specified input data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA1Update(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_update_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_update_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret != CRYPTO_SUCCESS) {
+ /* the update failed, free context and bail */
+ kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t));
+ ctx->cc_provider_private = NULL;
+ digest->cd_length = 0;
+ return (ret);
+ }
+
+ /*
+ * Do a SHA1 final, must be done separately since the digest
+ * type can be different than the input data type.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA1Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &PROV_SHA1_CTX(ctx)->sc_sha1_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_final_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ digest, SHA1_DIGEST_LENGTH, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_final_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ digest, SHA1_DIGEST_LENGTH, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ /* all done, free context and return */
+
+ if (ret == CRYPTO_SUCCESS) {
+ digest->cd_length = SHA1_DIGEST_LENGTH;
+ } else {
+ digest->cd_length = 0;
+ }
+
+ kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t));
+ ctx->cc_provider_private = NULL;
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha1_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * Do the SHA1 update on the specified input data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA1Update(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_update_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_update_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha1_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((digest->cd_length == 0) ||
+ (digest->cd_length < SHA1_DIGEST_LENGTH)) {
+ digest->cd_length = SHA1_DIGEST_LENGTH;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do a SHA1 final.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA1Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &PROV_SHA1_CTX(ctx)->sc_sha1_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_final_uio(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ digest, SHA1_DIGEST_LENGTH, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_final_mblk(&PROV_SHA1_CTX(ctx)->sc_sha1_ctx,
+ digest, SHA1_DIGEST_LENGTH, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ /* all done, free context and return */
+
+ if (ret == CRYPTO_SUCCESS) {
+ digest->cd_length = SHA1_DIGEST_LENGTH;
+ } else {
+ digest->cd_length = 0;
+ }
+
+ kmem_free(ctx->cc_provider_private, sizeof (sha1_ctx_t));
+ ctx->cc_provider_private = NULL;
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha1_digest_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_data_t *data, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ SHA1_CTX sha1_ctx;
+
+ if (mechanism->cm_type != SHA1_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /*
+ * Do the SHA1 init.
+ */
+ SHA1Init(&sha1_ctx);
+
+ /*
+ * Do the SHA1 update on the specified input data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA1Update(&sha1_ctx,
+ (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_update_uio(&sha1_ctx, data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_update_mblk(&sha1_ctx, data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret != CRYPTO_SUCCESS) {
+ /* the update failed, bail */
+ digest->cd_length = 0;
+ return (ret);
+ }
+
+ /*
+ * Do a SHA1 final, must be done separately since the digest
+ * type can be different than the input data type.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA1Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &sha1_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_final_uio(&sha1_ctx, digest,
+ SHA1_DIGEST_LENGTH, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_final_mblk(&sha1_ctx, digest,
+ SHA1_DIGEST_LENGTH, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS) {
+ digest->cd_length = SHA1_DIGEST_LENGTH;
+ } else {
+ digest->cd_length = 0;
+ }
+
+ return (ret);
+}
+
+/*
+ * KCF software provider mac entry points.
+ *
+ * SHA1 HMAC is: SHA1(key XOR opad, SHA1(key XOR ipad, text))
+ *
+ * Init:
+ * The initialization routine initializes what we denote
+ * as the inner and outer contexts by doing
+ * - for inner context: SHA1(key XOR ipad)
+ * - for outer context: SHA1(key XOR opad)
+ *
+ * Update:
+ * Each subsequent SHA1 HMAC update will result in an
+ * update of the inner context with the specified data.
+ *
+ * Final:
+ * The SHA1 HMAC final will do a SHA1 final operation on the
+ * inner context, and the resulting digest will be used
+ * as the data for an update on the outer context. Last
+ * but not least, a SHA1 final on the outer context will
+ * be performed to obtain the SHA1 HMAC digest to return
+ * to the user.
+ */
+
+/*
+ * Initialize a SHA1-HMAC context.
+ */
+static void
+sha1_mac_init_ctx(sha1_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
+{
+ uint32_t ipad[SHA1_HMAC_INTS_PER_BLOCK];
+ uint32_t opad[SHA1_HMAC_INTS_PER_BLOCK];
+ uint_t i;
+
+ bzero(ipad, SHA1_HMAC_BLOCK_SIZE);
+ bzero(opad, SHA1_HMAC_BLOCK_SIZE);
+
+ bcopy(keyval, ipad, length_in_bytes);
+ bcopy(keyval, opad, length_in_bytes);
+
+ /* XOR key with ipad (0x36) and opad (0x5c) */
+ for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
+ ipad[i] ^= 0x36363636;
+ opad[i] ^= 0x5c5c5c5c;
+ }
+
+ /* perform SHA1 on ipad */
+ SHA1Init(&ctx->hc_icontext);
+ SHA1Update(&ctx->hc_icontext, (uint8_t *)ipad, SHA1_HMAC_BLOCK_SIZE);
+
+ /* perform SHA1 on opad */
+ SHA1Init(&ctx->hc_ocontext);
+ SHA1Update(&ctx->hc_ocontext, (uint8_t *)opad, SHA1_HMAC_BLOCK_SIZE);
+}
+
+/*
+ */
+static int
+sha1_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE &&
+ mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ ctx->cc_provider_private = kmem_alloc(sizeof (sha1_hmac_ctx_t),
+ crypto_kmflag(req));
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, PROV_SHA1_HMAC_CTX(ctx),
+ sizeof (sha1_hmac_ctx_t));
+ } else {
+ /* no context template, compute context */
+ if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) {
+ uchar_t digested_key[SHA1_DIGEST_LENGTH];
+ sha1_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
+
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_SHA1_DIGEST_KEY(&hmac_ctx->hc_icontext,
+ key->ck_data, keylen_in_bytes, digested_key);
+ sha1_mac_init_ctx(PROV_SHA1_HMAC_CTX(ctx),
+ digested_key, SHA1_DIGEST_LENGTH);
+ } else {
+ sha1_mac_init_ctx(PROV_SHA1_HMAC_CTX(ctx),
+ key->ck_data, keylen_in_bytes);
+ }
+ }
+
+ /*
+ * Get the mechanism parameters, if applicable.
+ */
+ PROV_SHA1_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
+ if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t))
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ PROV_SHA1_GET_DIGEST_LEN(mechanism,
+ PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len);
+ if (PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len >
+ SHA1_DIGEST_LENGTH)
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ }
+
+ if (ret != CRYPTO_SUCCESS) {
+ bzero(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t));
+ kmem_free(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t));
+ ctx->cc_provider_private = NULL;
+ }
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha1_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * Do a SHA1 update of the inner context using the specified
+ * data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA1Update(&PROV_SHA1_HMAC_CTX(ctx)->hc_icontext,
+ (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_update_uio(
+ &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext, data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_update_mblk(
+ &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext, data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha1_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[SHA1_DIGEST_LENGTH];
+ uint32_t digest_len = SHA1_DIGEST_LENGTH;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ if (PROV_SHA1_HMAC_CTX(ctx)->hc_mech_type ==
+ SHA1_HMAC_GEN_MECH_INFO_TYPE)
+ digest_len = PROV_SHA1_HMAC_CTX(ctx)->hc_digest_len;
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
+ mac->cd_length = digest_len;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do a SHA1 final on the inner context.
+ */
+ SHA1Final(digest, &PROV_SHA1_HMAC_CTX(ctx)->hc_icontext);
+
+ /*
+ * Do a SHA1 update on the outer context, feeding the inner
+ * digest as data.
+ */
+ SHA1Update(&PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, digest,
+ SHA1_DIGEST_LENGTH);
+
+ /*
+ * Do a SHA1 final on the outer context, storing the computing
+ * digest in the users buffer.
+ */
+ switch (mac->cd_format) {
+ case CRYPTO_DATA_RAW:
+ if (digest_len != SHA1_DIGEST_LENGTH) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ SHA1Final(digest,
+ &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext);
+ bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len);
+ } else {
+ SHA1Final((unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset,
+ &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext);
+ }
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_final_uio(
+ &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_final_mblk(
+ &PROV_SHA1_HMAC_CTX(ctx)->hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS) {
+ mac->cd_length = digest_len;
+ } else {
+ mac->cd_length = 0;
+ }
+
+ bzero(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t));
+ kmem_free(ctx->cc_provider_private, sizeof (sha1_hmac_ctx_t));
+ ctx->cc_provider_private = NULL;
+
+ return (ret);
+}
+
+#define SHA1_MAC_UPDATE(data, ctx, ret) { \
+ switch (data->cd_format) { \
+ case CRYPTO_DATA_RAW: \
+ SHA1Update(&(ctx).hc_icontext, \
+ (uint8_t *)data->cd_raw.iov_base + \
+ data->cd_offset, data->cd_length); \
+ break; \
+ case CRYPTO_DATA_UIO: \
+ ret = sha1_digest_update_uio(&(ctx).hc_icontext, data); \
+ break; \
+ case CRYPTO_DATA_MBLK: \
+ ret = sha1_digest_update_mblk(&(ctx).hc_icontext, \
+ data); \
+ break; \
+ default: \
+ ret = CRYPTO_ARGUMENTS_BAD; \
+ } \
+}
+
+/* ARGSUSED */
+static int
+sha1_mac_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
+ crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[SHA1_DIGEST_LENGTH];
+ sha1_hmac_ctx_t sha1_hmac_ctx;
+ uint32_t digest_len = SHA1_DIGEST_LENGTH;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE &&
+ mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, &sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
+ } else {
+ /* no context template, initialize context */
+ if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) {
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx.hc_icontext,
+ key->ck_data, keylen_in_bytes, digest);
+ sha1_mac_init_ctx(&sha1_hmac_ctx, digest,
+ SHA1_DIGEST_LENGTH);
+ } else {
+ sha1_mac_init_ctx(&sha1_hmac_ctx, key->ck_data,
+ keylen_in_bytes);
+ }
+ }
+
+ /* get the mechanism parameters, if applicable */
+ if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t)) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ PROV_SHA1_GET_DIGEST_LEN(mechanism, digest_len);
+ if (digest_len > SHA1_DIGEST_LENGTH) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ }
+
+ /* do a SHA1 update of the inner context using the specified data */
+ SHA1_MAC_UPDATE(data, sha1_hmac_ctx, ret);
+ if (ret != CRYPTO_SUCCESS)
+ /* the update failed, free context and bail */
+ goto bail;
+
+ /*
+ * Do a SHA1 final on the inner context.
+ */
+ SHA1Final(digest, &sha1_hmac_ctx.hc_icontext);
+
+ /*
+ * Do an SHA1 update on the outer context, feeding the inner
+ * digest as data.
+ */
+ SHA1Update(&sha1_hmac_ctx.hc_ocontext, digest, SHA1_DIGEST_LENGTH);
+
+ /*
+ * Do a SHA1 final on the outer context, storing the computed
+ * digest in the users buffer.
+ */
+ switch (mac->cd_format) {
+ case CRYPTO_DATA_RAW:
+ if (digest_len != SHA1_DIGEST_LENGTH) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ SHA1Final(digest, &sha1_hmac_ctx.hc_ocontext);
+ bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len);
+ } else {
+ SHA1Final((unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, &sha1_hmac_ctx.hc_ocontext);
+ }
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha1_digest_final_uio(&sha1_hmac_ctx.hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha1_digest_final_mblk(&sha1_hmac_ctx.hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS) {
+ mac->cd_length = digest_len;
+ } else {
+ mac->cd_length = 0;
+ }
+ /* Extra paranoia: zeroize the context on the stack */
+ bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
+
+ return (ret);
+bail:
+ bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
+ mac->cd_length = 0;
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha1_mac_verify_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
+ crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[SHA1_DIGEST_LENGTH];
+ sha1_hmac_ctx_t sha1_hmac_ctx;
+ uint32_t digest_len = SHA1_DIGEST_LENGTH;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ if (mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE &&
+ mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)
+ return (CRYPTO_MECHANISM_INVALID);
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, &sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
+ } else {
+ /* no context template, initialize context */
+ if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) {
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx.hc_icontext,
+ key->ck_data, keylen_in_bytes, digest);
+ sha1_mac_init_ctx(&sha1_hmac_ctx, digest,
+ SHA1_DIGEST_LENGTH);
+ } else {
+ sha1_mac_init_ctx(&sha1_hmac_ctx, key->ck_data,
+ keylen_in_bytes);
+ }
+ }
+
+ /* get the mechanism parameters, if applicable */
+ if (mechanism->cm_type == SHA1_HMAC_GEN_MECH_INFO_TYPE) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t)) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ PROV_SHA1_GET_DIGEST_LEN(mechanism, digest_len);
+ if (digest_len > SHA1_DIGEST_LENGTH) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ }
+
+ if (mac->cd_length != digest_len) {
+ ret = CRYPTO_INVALID_MAC;
+ goto bail;
+ }
+
+ /* do a SHA1 update of the inner context using the specified data */
+ SHA1_MAC_UPDATE(data, sha1_hmac_ctx, ret);
+ if (ret != CRYPTO_SUCCESS)
+ /* the update failed, free context and bail */
+ goto bail;
+
+ /* do a SHA1 final on the inner context */
+ SHA1Final(digest, &sha1_hmac_ctx.hc_icontext);
+
+ /*
+ * Do an SHA1 update on the outer context, feeding the inner
+ * digest as data.
+ */
+ SHA1Update(&sha1_hmac_ctx.hc_ocontext, digest, SHA1_DIGEST_LENGTH);
+
+ /*
+ * Do a SHA1 final on the outer context, storing the computed
+ * digest in the users buffer.
+ */
+ SHA1Final(digest, &sha1_hmac_ctx.hc_ocontext);
+
+ /*
+ * Compare the computed digest against the expected digest passed
+ * as argument.
+ */
+
+ switch (mac->cd_format) {
+
+ case CRYPTO_DATA_RAW:
+ if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len) != 0)
+ ret = CRYPTO_INVALID_MAC;
+ break;
+
+ case CRYPTO_DATA_UIO: {
+ off_t offset = mac->cd_offset;
+ uint_t vec_idx;
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ /* we support only kernel buffer */
+ if (mac->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /* jump to the first iovec containing the expected digest */
+ for (vec_idx = 0;
+ offset >= mac->cd_uio->uio_iov[vec_idx].iov_len &&
+ vec_idx < mac->cd_uio->uio_iovcnt;
+ offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == mac->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is
+ * larger than the total size of the buffers
+ * it provided.
+ */
+ ret = CRYPTO_DATA_LEN_RANGE;
+ break;
+ }
+
+ /* do the comparison of computed digest vs specified one */
+ while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) {
+ cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+
+ if (bcmp(digest + scratch_offset,
+ mac->cd_uio->uio_iov[vec_idx].iov_base + offset,
+ cur_len) != 0) {
+ ret = CRYPTO_INVALID_MAC;
+ break;
+ }
+
+ length -= cur_len;
+ vec_idx++;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+ break;
+ }
+
+ case CRYPTO_DATA_MBLK: {
+ off_t offset = mac->cd_offset;
+ mblk_t *mp;
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ /* jump to the first mblk_t containing the expected digest */
+ for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than
+ * the total size of the buffers it provided.
+ */
+ ret = CRYPTO_DATA_LEN_RANGE;
+ break;
+ }
+
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ if (bcmp(digest + scratch_offset,
+ mp->b_rptr + offset, cur_len) != 0) {
+ ret = CRYPTO_INVALID_MAC;
+ break;
+ }
+
+ length -= cur_len;
+ mp = mp->b_cont;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+ break;
+ }
+
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
+ return (ret);
+bail:
+ bzero(&sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
+ mac->cd_length = 0;
+ return (ret);
+}
+
+/*
+ * KCF software provider context management entry points.
+ */
+
+/* ARGSUSED */
+static int
+sha1_create_ctx_template(crypto_provider_handle_t provider,
+ crypto_mechanism_t *mechanism, crypto_key_t *key,
+ crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
+ crypto_req_handle_t req)
+{
+ sha1_hmac_ctx_t *sha1_hmac_ctx_tmpl;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ if ((mechanism->cm_type != SHA1_HMAC_MECH_INFO_TYPE) &&
+ (mechanism->cm_type != SHA1_HMAC_GEN_MECH_INFO_TYPE)) {
+ return (CRYPTO_MECHANISM_INVALID);
+ }
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Allocate and initialize SHA1 context.
+ */
+ sha1_hmac_ctx_tmpl = kmem_alloc(sizeof (sha1_hmac_ctx_t),
+ crypto_kmflag(req));
+ if (sha1_hmac_ctx_tmpl == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ if (keylen_in_bytes > SHA1_HMAC_BLOCK_SIZE) {
+ uchar_t digested_key[SHA1_DIGEST_LENGTH];
+
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_SHA1_DIGEST_KEY(&sha1_hmac_ctx_tmpl->hc_icontext,
+ key->ck_data, keylen_in_bytes, digested_key);
+ sha1_mac_init_ctx(sha1_hmac_ctx_tmpl, digested_key,
+ SHA1_DIGEST_LENGTH);
+ } else {
+ sha1_mac_init_ctx(sha1_hmac_ctx_tmpl, key->ck_data,
+ keylen_in_bytes);
+ }
+
+ sha1_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
+ *ctx_template = (crypto_spi_ctx_template_t)sha1_hmac_ctx_tmpl;
+ *ctx_template_size = sizeof (sha1_hmac_ctx_t);
+
+
+ return (CRYPTO_SUCCESS);
+}
+
+static int
+sha1_free_context(crypto_ctx_t *ctx)
+{
+ uint_t ctx_len;
+ sha1_mech_type_t mech_type;
+
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_SUCCESS);
+
+ /*
+ * We have to free either SHA1 or SHA1-HMAC contexts, which
+ * have different lengths.
+ */
+
+ mech_type = PROV_SHA1_CTX(ctx)->sc_mech_type;
+ if (mech_type == SHA1_MECH_INFO_TYPE)
+ ctx_len = sizeof (sha1_ctx_t);
+ else {
+ ASSERT(mech_type == SHA1_HMAC_MECH_INFO_TYPE ||
+ mech_type == SHA1_HMAC_GEN_MECH_INFO_TYPE);
+ ctx_len = sizeof (sha1_hmac_ctx_t);
+ }
+
+ bzero(ctx->cc_provider_private, ctx_len);
+ kmem_free(ctx->cc_provider_private, ctx_len);
+ ctx->cc_provider_private = NULL;
+
+ return (CRYPTO_SUCCESS);
+}
diff --git a/usr/src/uts/common/crypto/io/sha2_mod.c b/usr/src/uts/common/crypto/io/sha2_mod.c
new file mode 100644
index 0000000000..cfdcae6bbf
--- /dev/null
+++ b/usr/src/uts/common/crypto/io/sha2_mod.c
@@ -0,0 +1,1618 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/modctl.h>
+#include <sys/cmn_err.h>
+#include <sys/crypto/common.h>
+#include <sys/crypto/spi.h>
+#include <sys/strsun.h>
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#define _SHA2_IMPL
+#include <sys/sha2.h>
+
+/*
+ * The sha2 module is created with two modlinkages:
+ * - a modlmisc that allows consumers to directly call the entry points
+ * SHA2Init, SHA2Update, and SHA2Final.
+ * - a modlcrypto that allows the module to register with the Kernel
+ * Cryptographic Framework (KCF) as a software provider for the SHA2
+ * mechanisms.
+ */
+
+static struct modlmisc modlmisc = {
+ &mod_miscops,
+ "SHA2 Message-Digest Algorithm"
+};
+
+static struct modlcrypto modlcrypto = {
+ &mod_cryptoops,
+ "SHA2 Kernel SW Provider %I%"
+};
+
+static struct modlinkage modlinkage = {
+ MODREV_1, &modlmisc, &modlcrypto, NULL
+};
+
+/*
+ * CSPI information (entry points, provider info, etc.)
+ */
+
+/*
+ * Context for SHA2 mechanism.
+ */
+typedef struct sha2_ctx {
+ sha2_mech_type_t sc_mech_type; /* type of context */
+ SHA2_CTX sc_sha2_ctx; /* SHA2 context */
+} sha2_ctx_t;
+
+/*
+ * Context for SHA2 HMAC and HMAC GENERAL mechanisms.
+ */
+typedef struct sha2_hmac_ctx {
+ sha2_mech_type_t hc_mech_type; /* type of context */
+ uint32_t hc_digest_len; /* digest len in bytes */
+ SHA2_CTX hc_icontext; /* inner SHA2 context */
+ SHA2_CTX hc_ocontext; /* outer SHA2 context */
+} sha2_hmac_ctx_t;
+
+/*
+ * Macros to access the SHA2 or SHA2-HMAC contexts from a context passed
+ * by KCF to one of the entry points.
+ */
+
+#define PROV_SHA2_CTX(ctx) ((sha2_ctx_t *)(ctx)->cc_provider_private)
+#define PROV_SHA2_HMAC_CTX(ctx) ((sha2_hmac_ctx_t *)(ctx)->cc_provider_private)
+
+/* to extract the digest length passed as mechanism parameter */
+#define PROV_SHA2_GET_DIGEST_LEN(m, len) { \
+ if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \
+ (len) = (uint32_t)*((ulong_t *)(m)->cm_param); \
+ else { \
+ ulong_t tmp_ulong; \
+ bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \
+ (len) = (uint32_t)tmp_ulong; \
+ } \
+}
+
+#define PROV_SHA2_DIGEST_KEY(mech, ctx, key, len, digest) { \
+ SHA2Init(mech, ctx); \
+ SHA2Update(ctx, key, len); \
+ SHA2Final(digest, ctx); \
+}
+
+/*
+ * Mechanism info structure passed to KCF during registration.
+ */
+static crypto_mech_info_t sha2_mech_info_tab[] = {
+ /* SHA256 */
+ {SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
+ CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
+ 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA256-HMAC */
+ {SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA256-HMAC GENERAL */
+ {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA384 */
+ {SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
+ CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
+ 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA384-HMAC */
+ {SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA384-HMAC GENERAL */
+ {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA512 */
+ {SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
+ CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
+ 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA512-HMAC */
+ {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS},
+ /* SHA512-HMAC GENERAL */
+ {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
+ CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
+ SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
+ CRYPTO_KEYSIZE_UNIT_IN_BITS}
+};
+
+static void sha2_provider_status(crypto_provider_handle_t, uint_t *);
+
+static crypto_control_ops_t sha2_control_ops = {
+ sha2_provider_status
+};
+
+static int sha2_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
+ crypto_req_handle_t);
+static int sha2_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int sha2_digest_update(crypto_ctx_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int sha2_digest_final(crypto_ctx_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int sha2_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
+ crypto_req_handle_t);
+
+static crypto_digest_ops_t sha2_digest_ops = {
+ sha2_digest_init,
+ sha2_digest,
+ sha2_digest_update,
+ NULL,
+ sha2_digest_final,
+ sha2_digest_atomic
+};
+
+static int sha2_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+static int sha2_mac_update(crypto_ctx_t *, crypto_data_t *,
+ crypto_req_handle_t);
+static int sha2_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
+static int sha2_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+static int sha2_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
+ crypto_spi_ctx_template_t, crypto_req_handle_t);
+
+static crypto_mac_ops_t sha2_mac_ops = {
+ sha2_mac_init,
+ NULL,
+ sha2_mac_update,
+ sha2_mac_final,
+ sha2_mac_atomic,
+ sha2_mac_verify_atomic
+};
+
+static int sha2_create_ctx_template(crypto_provider_handle_t,
+ crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
+ size_t *, crypto_req_handle_t);
+static int sha2_free_context(crypto_ctx_t *);
+
+static crypto_ctx_ops_t sha2_ctx_ops = {
+ sha2_create_ctx_template,
+ sha2_free_context
+};
+
+static crypto_ops_t sha2_crypto_ops = {
+ &sha2_control_ops,
+ &sha2_digest_ops,
+ NULL,
+ &sha2_mac_ops,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &sha2_ctx_ops
+};
+
+static crypto_provider_info_t sha2_prov_info = {
+ CRYPTO_SPI_VERSION_1,
+ "SHA2 Software Provider",
+ CRYPTO_SW_PROVIDER,
+ {&modlinkage},
+ NULL,
+ &sha2_crypto_ops,
+ sizeof (sha2_mech_info_tab)/sizeof (crypto_mech_info_t),
+ sha2_mech_info_tab
+};
+
+static crypto_kcf_provider_handle_t sha2_prov_handle = NULL;
+
+int
+_init()
+{
+ int ret;
+
+ if ((ret = mod_install(&modlinkage)) != 0)
+ return (ret);
+
+ /*
+ * Register with KCF. If the registration fails, log an
+ * error but do not uninstall the module, since the functionality
+ * provided by misc/sha2 should still be available.
+ */
+ if ((ret = crypto_register_provider(&sha2_prov_info,
+ &sha2_prov_handle)) != CRYPTO_SUCCESS)
+ cmn_err(CE_WARN, "sha2 _init: "
+ "crypto_register_provider() failed (0x%x)", ret);
+
+ return (0);
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+ return (mod_info(&modlinkage, modinfop));
+}
+
+/*
+ * KCF software provider control entry points.
+ */
+/* ARGSUSED */
+static void
+sha2_provider_status(crypto_provider_handle_t provider, uint_t *status)
+{
+ *status = CRYPTO_PROVIDER_READY;
+}
+
+/*
+ * KCF software provider digest entry points.
+ */
+
+static int
+sha2_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
+ crypto_req_handle_t req)
+{
+
+ /*
+ * Allocate and initialize SHA2 context.
+ */
+ ctx->cc_provider_private = kmem_alloc(sizeof (sha2_ctx_t),
+ crypto_kmflag(req));
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ PROV_SHA2_CTX(ctx)->sc_mech_type = mechanism->cm_type;
+ SHA2Init(mechanism->cm_type, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper SHA2 digest update function for uio data.
+ */
+static int
+sha2_digest_update_uio(SHA2_CTX *sha2_ctx, crypto_data_t *data)
+{
+ off_t offset = data->cd_offset;
+ size_t length = data->cd_length;
+ uint_t vec_idx;
+ size_t cur_len;
+
+ /* we support only kernel buffer */
+ if (data->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Jump to the first iovec containing data to be
+ * digested.
+ */
+ for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt &&
+ offset >= data->cd_uio->uio_iov[vec_idx].iov_len;
+ offset -= data->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == data->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ /*
+ * Now do the digesting on the iovecs.
+ */
+ while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) {
+ cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+
+ SHA2Update(sha2_ctx, (uint8_t *)data->cd_uio->
+ uio_iov[vec_idx].iov_base + offset, cur_len);
+ length -= cur_len;
+ vec_idx++;
+ offset = 0;
+ }
+
+ if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) {
+ /*
+ * The end of the specified iovec's was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper SHA2 digest final function for uio data.
+ * digest_len is the length of the desired digest. If digest_len
+ * is smaller than the default SHA2 digest length, the caller
+ * must pass a scratch buffer, digest_scratch, which must
+ * be at least the algorithm's digest length bytes.
+ */
+static int
+sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest,
+ ulong_t digest_len, uchar_t *digest_scratch)
+{
+ off_t offset = digest->cd_offset;
+ uint_t vec_idx;
+
+ /* we support only kernel buffer */
+ if (digest->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Jump to the first iovec containing ptr to the digest to
+ * be returned.
+ */
+ for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len &&
+ vec_idx < digest->cd_uio->uio_iovcnt;
+ offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == digest->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is
+ * larger than the total size of the buffers
+ * it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ if (offset + digest_len <=
+ digest->cd_uio->uio_iov[vec_idx].iov_len) {
+ /*
+ * The computed SHA2 digest will fit in the current
+ * iovec.
+ */
+ if (((sha2_ctx->algotype <= SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
+ (digest_len != SHA256_DIGEST_LENGTH)) ||
+ ((sha2_ctx->algotype > SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
+ (digest_len != SHA512_DIGEST_LENGTH))) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ SHA2Final(digest_scratch, sha2_ctx);
+
+ bcopy(digest_scratch, (uchar_t *)digest->
+ cd_uio->uio_iov[vec_idx].iov_base + offset,
+ digest_len);
+ } else {
+ SHA2Final((uchar_t *)digest->
+ cd_uio->uio_iov[vec_idx].iov_base + offset,
+ sha2_ctx);
+
+ }
+ } else {
+ /*
+ * The computed digest will be crossing one or more iovec's.
+ * This is bad performance-wise but we need to support it.
+ * Allocate a small scratch buffer on the stack and
+ * copy it piece meal to the specified digest iovec's.
+ */
+ uchar_t digest_tmp[SHA512_DIGEST_LENGTH];
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ SHA2Final(digest_tmp, sha2_ctx);
+
+ while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) {
+ cur_len =
+ MIN(digest->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+ bcopy(digest_tmp + scratch_offset,
+ digest->cd_uio->uio_iov[vec_idx].iov_base + offset,
+ cur_len);
+
+ length -= cur_len;
+ vec_idx++;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+
+ if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) {
+ /*
+ * The end of the specified iovec's was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it
+ * provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper SHA2 digest update for mblk's.
+ */
+static int
+sha2_digest_update_mblk(SHA2_CTX *sha2_ctx, crypto_data_t *data)
+{
+ off_t offset = data->cd_offset;
+ size_t length = data->cd_length;
+ mblk_t *mp;
+ size_t cur_len;
+
+ /*
+ * Jump to the first mblk_t containing data to be digested.
+ */
+ for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ /*
+ * Now do the digesting on the mblk chain.
+ */
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ SHA2Update(sha2_ctx, mp->b_rptr + offset, cur_len);
+ length -= cur_len;
+ offset = 0;
+ mp = mp->b_cont;
+ }
+
+ if (mp == NULL && length > 0) {
+ /*
+ * The end of the mblk was reached but the length requested
+ * could not be processed, i.e. The caller requested
+ * to digest more data than it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/*
+ * Helper SHA2 digest final for mblk's.
+ * digest_len is the length of the desired digest. If digest_len
+ * is smaller than the default SHA2 digest length, the caller
+ * must pass a scratch buffer, digest_scratch, which must
+ * be at least the algorithm's digest length bytes.
+ */
+static int
+sha2_digest_final_mblk(SHA2_CTX *sha2_ctx, crypto_data_t *digest,
+ ulong_t digest_len, uchar_t *digest_scratch)
+{
+ off_t offset = digest->cd_offset;
+ mblk_t *mp;
+
+ /*
+ * Jump to the first mblk_t that will be used to store the digest.
+ */
+ for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than the
+ * total size of the buffers it provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+
+ if (offset + digest_len <= MBLKL(mp)) {
+ /*
+ * The computed SHA2 digest will fit in the current mblk.
+ * Do the SHA2Final() in-place.
+ */
+ if (((sha2_ctx->algotype <= SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
+ (digest_len != SHA256_DIGEST_LENGTH)) ||
+ ((sha2_ctx->algotype > SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
+ (digest_len != SHA512_DIGEST_LENGTH))) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ SHA2Final(digest_scratch, sha2_ctx);
+ bcopy(digest_scratch, mp->b_rptr + offset, digest_len);
+ } else {
+ SHA2Final(mp->b_rptr + offset, sha2_ctx);
+ }
+ } else {
+ /*
+ * The computed digest will be crossing one or more mblk's.
+ * This is bad performance-wise but we need to support it.
+ * Allocate a small scratch buffer on the stack and
+ * copy it piece meal to the specified digest iovec's.
+ */
+ uchar_t digest_tmp[SHA512_DIGEST_LENGTH];
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ SHA2Final(digest_tmp, sha2_ctx);
+
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ bcopy(digest_tmp + scratch_offset,
+ mp->b_rptr + offset, cur_len);
+
+ length -= cur_len;
+ mp = mp->b_cont;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+
+ if (mp == NULL && length > 0) {
+ /*
+ * The end of the specified mblk was reached but
+ * the length requested could not be processed, i.e.
+ * The caller requested to digest more data than it
+ * provided.
+ */
+ return (CRYPTO_DATA_LEN_RANGE);
+ }
+ }
+
+ return (CRYPTO_SUCCESS);
+}
+
+/* ARGSUSED */
+static int
+sha2_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uint_t sha_digest_len;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
+ case SHA256_MECH_INFO_TYPE:
+ sha_digest_len = SHA256_DIGEST_LENGTH;
+ break;
+ case SHA384_MECH_INFO_TYPE:
+ sha_digest_len = SHA384_DIGEST_LENGTH;
+ break;
+ case SHA512_MECH_INFO_TYPE:
+ sha_digest_len = SHA512_DIGEST_LENGTH;
+ break;
+ default:
+ return (CRYPTO_MECHANISM_INVALID);
+ }
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((digest->cd_length == 0) ||
+ (digest->cd_length < sha_digest_len)) {
+ digest->cd_length = sha_digest_len;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do the SHA2 update on the specified input data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_update_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret != CRYPTO_SUCCESS) {
+ /* the update failed, free context and bail */
+ kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
+ ctx->cc_provider_private = NULL;
+ digest->cd_length = 0;
+ return (ret);
+ }
+
+ /*
+ * Do a SHA2 final, must be done separately since the digest
+ * type can be different than the input data type.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA2Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ digest, sha_digest_len, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_final_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ digest, sha_digest_len, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ /* all done, free context and return */
+
+ if (ret == CRYPTO_SUCCESS)
+ digest->cd_length = sha_digest_len;
+ else
+ digest->cd_length = 0;
+
+ kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
+ ctx->cc_provider_private = NULL;
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha2_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * Do the SHA2 update on the specified input data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_update_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha2_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uint_t sha_digest_len;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
+ case SHA256_MECH_INFO_TYPE:
+ sha_digest_len = SHA256_DIGEST_LENGTH;
+ break;
+ case SHA384_MECH_INFO_TYPE:
+ sha_digest_len = SHA384_DIGEST_LENGTH;
+ break;
+ case SHA512_MECH_INFO_TYPE:
+ sha_digest_len = SHA512_DIGEST_LENGTH;
+ break;
+ default:
+ return (CRYPTO_MECHANISM_INVALID);
+ }
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((digest->cd_length == 0) ||
+ (digest->cd_length < sha_digest_len)) {
+ digest->cd_length = sha_digest_len;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do a SHA2 final.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA2Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ digest, sha_digest_len, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_final_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
+ digest, sha_digest_len, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ /* all done, free context and return */
+
+ if (ret == CRYPTO_SUCCESS)
+ digest->cd_length = sha_digest_len;
+ else
+ digest->cd_length = 0;
+
+ kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
+ ctx->cc_provider_private = NULL;
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha2_digest_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_data_t *data, crypto_data_t *digest,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ SHA2_CTX sha2_ctx;
+ uint32_t sha_digest_len;
+
+ /*
+ * Do the SHA inits.
+ */
+
+ SHA2Init(mechanism->cm_type, &sha2_ctx);
+
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA2Update(&sha2_ctx, (uint8_t *)data->
+ cd_raw.iov_base + data->cd_offset, data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_update_uio(&sha2_ctx, data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_update_mblk(&sha2_ctx, data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ /*
+ * Do the SHA updates on the specified input data.
+ */
+
+ if (ret != CRYPTO_SUCCESS) {
+ /* the update failed, bail */
+ digest->cd_length = 0;
+ return (ret);
+ }
+
+ if (mechanism->cm_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE)
+ sha_digest_len = SHA256_DIGEST_LENGTH;
+ else
+ sha_digest_len = SHA512_DIGEST_LENGTH;
+
+ /*
+ * Do a SHA2 final, must be done separately since the digest
+ * type can be different than the input data type.
+ */
+ switch (digest->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA2Final((unsigned char *)digest->cd_raw.iov_base +
+ digest->cd_offset, &sha2_ctx);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_final_uio(&sha2_ctx, digest,
+ sha_digest_len, NULL);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_final_mblk(&sha2_ctx, digest,
+ sha_digest_len, NULL);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS)
+ digest->cd_length = sha_digest_len;
+ else
+ digest->cd_length = 0;
+
+ return (ret);
+}
+
+/*
+ * KCF software provider mac entry points.
+ *
+ * SHA2 HMAC is: SHA2(key XOR opad, SHA2(key XOR ipad, text))
+ *
+ * Init:
+ * The initialization routine initializes what we denote
+ * as the inner and outer contexts by doing
+ * - for inner context: SHA2(key XOR ipad)
+ * - for outer context: SHA2(key XOR opad)
+ *
+ * Update:
+ * Each subsequent SHA2 HMAC update will result in an
+ * update of the inner context with the specified data.
+ *
+ * Final:
+ * The SHA2 HMAC final will do a SHA2 final operation on the
+ * inner context, and the resulting digest will be used
+ * as the data for an update on the outer context. Last
+ * but not least, a SHA2 final on the outer context will
+ * be performed to obtain the SHA2 HMAC digest to return
+ * to the user.
+ */
+
+/*
+ * Initialize a SHA2-HMAC context.
+ */
+static void
+sha2_mac_init_ctx(sha2_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
+{
+ uint64_t ipad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
+ uint64_t opad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
+ int i, block_size, blocks_per_int64;
+
+ /* Determine the block size */
+ if (ctx->hc_mech_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) {
+ block_size = SHA256_HMAC_BLOCK_SIZE;
+ blocks_per_int64 = SHA256_HMAC_BLOCK_SIZE / sizeof (uint64_t);
+ } else {
+ block_size = SHA512_HMAC_BLOCK_SIZE;
+ blocks_per_int64 = SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t);
+ }
+
+ (void) bzero(ipad, block_size);
+ (void) bzero(opad, block_size);
+ (void) bcopy(keyval, ipad, length_in_bytes);
+ (void) bcopy(keyval, opad, length_in_bytes);
+
+ /* XOR key with ipad (0x36) and opad (0x5c) */
+ for (i = 0; i < blocks_per_int64; i ++) {
+ ipad[i] ^= 0x3636363636363636;
+ opad[i] ^= 0x5c5c5c5c5c5c5c5c;
+ }
+
+ /* perform SHA2 on ipad */
+ SHA2Init(ctx->hc_mech_type, &ctx->hc_icontext);
+ SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
+
+ /* perform SHA2 on opad */
+ SHA2Init(ctx->hc_mech_type, &ctx->hc_ocontext);
+ SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
+
+}
+
+/*
+ */
+static int
+sha2_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+ uint_t sha_digest_len, sha_hmac_block_size;
+
+ /*
+ * Set the digest length and block size to values approriate to the
+ * mechanism
+ */
+ switch (mechanism->cm_type) {
+ case SHA256_HMAC_MECH_INFO_TYPE:
+ case SHA256_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = SHA256_DIGEST_LENGTH;
+ sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
+ break;
+ case SHA384_HMAC_MECH_INFO_TYPE:
+ case SHA384_HMAC_GEN_MECH_INFO_TYPE:
+ case SHA512_HMAC_MECH_INFO_TYPE:
+ case SHA512_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = SHA512_DIGEST_LENGTH;
+ sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
+ break;
+ default:
+ return (CRYPTO_MECHANISM_INVALID);
+ }
+
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ ctx->cc_provider_private = kmem_alloc(sizeof (sha2_hmac_ctx_t),
+ crypto_kmflag(req));
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, PROV_SHA2_HMAC_CTX(ctx),
+ sizeof (sha2_hmac_ctx_t));
+ } else {
+ /* no context template, compute context */
+ if (keylen_in_bytes > sha_hmac_block_size) {
+ uchar_t digested_key[SHA512_DIGEST_LENGTH];
+ sha2_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
+
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
+ &hmac_ctx->hc_icontext,
+ key->ck_data, keylen_in_bytes, digested_key);
+ sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx),
+ digested_key, sha_digest_len);
+ } else {
+ sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx),
+ key->ck_data, keylen_in_bytes);
+ }
+ }
+
+ /*
+ * Get the mechanism parameters, if applicable.
+ */
+ PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
+ if (mechanism->cm_type % 3 == 2) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t))
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ PROV_SHA2_GET_DIGEST_LEN(mechanism,
+ PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len);
+ if (PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len > sha_digest_len)
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ }
+
+ if (ret != CRYPTO_SUCCESS) {
+ bzero(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
+ kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
+ ctx->cc_provider_private = NULL;
+ }
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha2_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
+ crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /*
+ * Do a SHA2 update of the inner context using the specified
+ * data.
+ */
+ switch (data->cd_format) {
+ case CRYPTO_DATA_RAW:
+ SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_icontext,
+ (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
+ data->cd_length);
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_update_uio(
+ &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, data);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_update_mblk(
+ &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, data);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha2_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[SHA512_DIGEST_LENGTH];
+ uint32_t digest_len, sha_digest_len;
+
+ ASSERT(ctx->cc_provider_private != NULL);
+
+ /* Set the digest lengths to values approriate to the mechanism */
+ switch (PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type) {
+ case SHA256_HMAC_MECH_INFO_TYPE:
+ sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
+ break;
+ case SHA384_HMAC_MECH_INFO_TYPE:
+ case SHA512_HMAC_MECH_INFO_TYPE:
+ sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
+ break;
+ case SHA256_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = SHA256_DIGEST_LENGTH;
+ digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len;
+ break;
+ case SHA384_HMAC_GEN_MECH_INFO_TYPE:
+ case SHA512_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = SHA512_DIGEST_LENGTH;
+ digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len;
+ break;
+ }
+
+ /*
+ * We need to just return the length needed to store the output.
+ * We should not destroy the context for the following cases.
+ */
+ if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
+ mac->cd_length = digest_len;
+ return (CRYPTO_BUFFER_TOO_SMALL);
+ }
+
+ /*
+ * Do a SHA2 final on the inner context.
+ */
+ SHA2Final(digest, &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext);
+
+ /*
+ * Do a SHA2 update on the outer context, feeding the inner
+ * digest as data.
+ */
+ SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, digest,
+ sha_digest_len);
+
+ /*
+ * Do a SHA2 final on the outer context, storing the computing
+ * digest in the users buffer.
+ */
+ switch (mac->cd_format) {
+ case CRYPTO_DATA_RAW:
+ if (digest_len != sha_digest_len) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ SHA2Final(digest,
+ &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext);
+ bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len);
+ } else {
+ SHA2Final((unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset,
+ &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext);
+ }
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_final_uio(
+ &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_final_mblk(
+ &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS)
+ mac->cd_length = digest_len;
+ else
+ mac->cd_length = 0;
+
+ bzero(&PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, sizeof (sha2_hmac_ctx_t));
+ kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
+ ctx->cc_provider_private = NULL;
+
+ return (ret);
+}
+
+#define SHA2_MAC_UPDATE(data, ctx, ret) { \
+ switch (data->cd_format) { \
+ case CRYPTO_DATA_RAW: \
+ SHA2Update(&(ctx).hc_icontext, \
+ (uint8_t *)data->cd_raw.iov_base + \
+ data->cd_offset, data->cd_length); \
+ break; \
+ case CRYPTO_DATA_UIO: \
+ ret = sha2_digest_update_uio(&(ctx).hc_icontext, data); \
+ break; \
+ case CRYPTO_DATA_MBLK: \
+ ret = sha2_digest_update_mblk(&(ctx).hc_icontext, \
+ data); \
+ break; \
+ default: \
+ ret = CRYPTO_ARGUMENTS_BAD; \
+ } \
+}
+
+/* ARGSUSED */
+static int
+sha2_mac_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
+ crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[SHA512_DIGEST_LENGTH];
+ sha2_hmac_ctx_t sha2_hmac_ctx;
+ uint32_t sha_digest_len, digest_len, sha_hmac_block_size;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ /*
+ * Set the digest length and block size to values approriate to the
+ * mechanism
+ */
+ switch (mechanism->cm_type) {
+ case SHA256_HMAC_MECH_INFO_TYPE:
+ case SHA256_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
+ sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
+ break;
+ case SHA384_HMAC_MECH_INFO_TYPE:
+ case SHA384_HMAC_GEN_MECH_INFO_TYPE:
+ case SHA512_HMAC_MECH_INFO_TYPE:
+ case SHA512_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
+ sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
+ break;
+ default:
+ return (CRYPTO_MECHANISM_INVALID);
+ }
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, &sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
+ } else {
+ sha2_hmac_ctx.hc_mech_type = mechanism->cm_type;
+ /* no context template, initialize context */
+ if (keylen_in_bytes > sha_hmac_block_size) {
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
+ &sha2_hmac_ctx.hc_icontext,
+ key->ck_data, keylen_in_bytes, digest);
+ sha2_mac_init_ctx(&sha2_hmac_ctx, digest,
+ sha_digest_len);
+ } else {
+ sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data,
+ keylen_in_bytes);
+ }
+ }
+
+ /* get the mechanism parameters, if applicable */
+ if ((mechanism->cm_type % 3) == 2) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t)) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ PROV_SHA2_GET_DIGEST_LEN(mechanism, digest_len);
+ if (digest_len > sha_digest_len) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ }
+
+ /* do a SHA2 update of the inner context using the specified data */
+ SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret);
+ if (ret != CRYPTO_SUCCESS)
+ /* the update failed, free context and bail */
+ goto bail;
+
+ /*
+ * Do a SHA2 final on the inner context.
+ */
+ SHA2Final(digest, &sha2_hmac_ctx.hc_icontext);
+
+ /*
+ * Do an SHA2 update on the outer context, feeding the inner
+ * digest as data.
+ *
+ * Make sure that SHA384 is handled special because
+ * it cannot feed a 60-byte inner hash to the outer
+ */
+ if (mechanism->cm_type == SHA384_HMAC_MECH_INFO_TYPE ||
+ mechanism->cm_type == SHA384_HMAC_GEN_MECH_INFO_TYPE)
+ SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest,
+ SHA384_DIGEST_LENGTH);
+ else
+ SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len);
+
+ /*
+ * Do a SHA2 final on the outer context, storing the computed
+ * digest in the users buffer.
+ */
+ switch (mac->cd_format) {
+ case CRYPTO_DATA_RAW:
+ if (digest_len != sha_digest_len) {
+ /*
+ * The caller requested a short digest. Digest
+ * into a scratch buffer and return to
+ * the user only what was requested.
+ */
+ SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext);
+ bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len);
+ } else {
+ SHA2Final((unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, &sha2_hmac_ctx.hc_ocontext);
+ }
+ break;
+ case CRYPTO_DATA_UIO:
+ ret = sha2_digest_final_uio(&sha2_hmac_ctx.hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ case CRYPTO_DATA_MBLK:
+ ret = sha2_digest_final_mblk(&sha2_hmac_ctx.hc_ocontext, mac,
+ digest_len, digest);
+ break;
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ if (ret == CRYPTO_SUCCESS) {
+ mac->cd_length = digest_len;
+ return (CRYPTO_SUCCESS);
+ }
+bail:
+ bzero(&sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
+ mac->cd_length = 0;
+ return (ret);
+}
+
+/* ARGSUSED */
+static int
+sha2_mac_verify_atomic(crypto_provider_handle_t provider,
+ crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
+ crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
+ crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
+{
+ int ret = CRYPTO_SUCCESS;
+ uchar_t digest[SHA512_DIGEST_LENGTH];
+ sha2_hmac_ctx_t sha2_hmac_ctx;
+ uint32_t sha_digest_len, digest_len, sha_hmac_block_size;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+
+ /*
+ * Set the digest length and block size to values approriate to the
+ * mechanism
+ */
+ switch (mechanism->cm_type) {
+ case SHA256_HMAC_MECH_INFO_TYPE:
+ case SHA256_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
+ sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
+ break;
+ case SHA384_HMAC_MECH_INFO_TYPE:
+ case SHA384_HMAC_GEN_MECH_INFO_TYPE:
+ case SHA512_HMAC_MECH_INFO_TYPE:
+ case SHA512_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
+ sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
+ break;
+ default:
+ return (CRYPTO_MECHANISM_INVALID);
+ }
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ if (ctx_template != NULL) {
+ /* reuse context template */
+ bcopy(ctx_template, &sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
+ } else {
+ /* no context template, initialize context */
+ if (keylen_in_bytes > sha_hmac_block_size) {
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
+ &sha2_hmac_ctx.hc_icontext,
+ key->ck_data, keylen_in_bytes, digest);
+ sha2_mac_init_ctx(&sha2_hmac_ctx, digest,
+ sha_digest_len);
+ } else {
+ sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data,
+ keylen_in_bytes);
+ }
+ }
+
+ /* get the mechanism parameters, if applicable */
+ if (mechanism->cm_type % 3 == 2) {
+ if (mechanism->cm_param == NULL ||
+ mechanism->cm_param_len != sizeof (ulong_t)) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ PROV_SHA2_GET_DIGEST_LEN(mechanism, digest_len);
+ if (digest_len > sha_digest_len) {
+ ret = CRYPTO_MECHANISM_PARAM_INVALID;
+ goto bail;
+ }
+ }
+
+ if (mac->cd_length != digest_len) {
+ ret = CRYPTO_INVALID_MAC;
+ goto bail;
+ }
+
+ /* do a SHA2 update of the inner context using the specified data */
+ SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret);
+ if (ret != CRYPTO_SUCCESS)
+ /* the update failed, free context and bail */
+ goto bail;
+
+ /* do a SHA2 final on the inner context */
+ SHA2Final(digest, &sha2_hmac_ctx.hc_icontext);
+
+ /*
+ * Do an SHA2 update on the outer context, feeding the inner
+ * digest as data.
+ */
+ SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len);
+
+ /*
+ * Do a SHA2 final on the outer context, storing the computed
+ * digest in the users buffer.
+ */
+ SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext);
+
+ /*
+ * Compare the computed digest against the expected digest passed
+ * as argument.
+ */
+
+ switch (mac->cd_format) {
+
+ case CRYPTO_DATA_RAW:
+ if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
+ mac->cd_offset, digest_len) != 0)
+ ret = CRYPTO_INVALID_MAC;
+ break;
+
+ case CRYPTO_DATA_UIO: {
+ off_t offset = mac->cd_offset;
+ uint_t vec_idx;
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ /* we support only kernel buffer */
+ if (mac->cd_uio->uio_segflg != UIO_SYSSPACE)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /* jump to the first iovec containing the expected digest */
+ for (vec_idx = 0;
+ offset >= mac->cd_uio->uio_iov[vec_idx].iov_len &&
+ vec_idx < mac->cd_uio->uio_iovcnt;
+ offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len);
+ if (vec_idx == mac->cd_uio->uio_iovcnt) {
+ /*
+ * The caller specified an offset that is
+ * larger than the total size of the buffers
+ * it provided.
+ */
+ ret = CRYPTO_DATA_LEN_RANGE;
+ break;
+ }
+
+ /* do the comparison of computed digest vs specified one */
+ while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) {
+ cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len -
+ offset, length);
+
+ if (bcmp(digest + scratch_offset,
+ mac->cd_uio->uio_iov[vec_idx].iov_base + offset,
+ cur_len) != 0) {
+ ret = CRYPTO_INVALID_MAC;
+ break;
+ }
+
+ length -= cur_len;
+ vec_idx++;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+ break;
+ }
+
+ case CRYPTO_DATA_MBLK: {
+ off_t offset = mac->cd_offset;
+ mblk_t *mp;
+ off_t scratch_offset = 0;
+ size_t length = digest_len;
+ size_t cur_len;
+
+ /* jump to the first mblk_t containing the expected digest */
+ for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp);
+ offset -= MBLKL(mp), mp = mp->b_cont);
+ if (mp == NULL) {
+ /*
+ * The caller specified an offset that is larger than
+ * the total size of the buffers it provided.
+ */
+ ret = CRYPTO_DATA_LEN_RANGE;
+ break;
+ }
+
+ while (mp != NULL && length > 0) {
+ cur_len = MIN(MBLKL(mp) - offset, length);
+ if (bcmp(digest + scratch_offset,
+ mp->b_rptr + offset, cur_len) != 0) {
+ ret = CRYPTO_INVALID_MAC;
+ break;
+ }
+
+ length -= cur_len;
+ mp = mp->b_cont;
+ scratch_offset += cur_len;
+ offset = 0;
+ }
+ break;
+ }
+
+ default:
+ ret = CRYPTO_ARGUMENTS_BAD;
+ }
+
+ return (ret);
+bail:
+ bzero(&sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
+ mac->cd_length = 0;
+ return (ret);
+}
+
+/*
+ * KCF software provider context management entry points.
+ */
+
+/* ARGSUSED */
+static int
+sha2_create_ctx_template(crypto_provider_handle_t provider,
+ crypto_mechanism_t *mechanism, crypto_key_t *key,
+ crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
+ crypto_req_handle_t req)
+{
+ sha2_hmac_ctx_t *sha2_hmac_ctx_tmpl;
+ uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
+ uint32_t sha_digest_len, sha_hmac_block_size;
+
+ /*
+ * Set the digest length and block size to values approriate to the
+ * mechanism
+ */
+ switch (mechanism->cm_type) {
+ case SHA256_HMAC_MECH_INFO_TYPE:
+ case SHA256_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = SHA256_DIGEST_LENGTH;
+ sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
+ break;
+ case SHA384_HMAC_MECH_INFO_TYPE:
+ case SHA384_HMAC_GEN_MECH_INFO_TYPE:
+ case SHA512_HMAC_MECH_INFO_TYPE:
+ case SHA512_HMAC_GEN_MECH_INFO_TYPE:
+ sha_digest_len = SHA512_DIGEST_LENGTH;
+ sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
+ break;
+ default:
+ return (CRYPTO_MECHANISM_INVALID);
+ }
+
+ /* Add support for key by attributes (RFE 4706552) */
+ if (key->ck_format != CRYPTO_KEY_RAW)
+ return (CRYPTO_ARGUMENTS_BAD);
+
+ /*
+ * Allocate and initialize SHA2 context.
+ */
+ sha2_hmac_ctx_tmpl = kmem_alloc(sizeof (sha2_hmac_ctx_t),
+ crypto_kmflag(req));
+ if (sha2_hmac_ctx_tmpl == NULL)
+ return (CRYPTO_HOST_MEMORY);
+
+ sha2_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
+
+ if (keylen_in_bytes > sha_hmac_block_size) {
+ uchar_t digested_key[SHA512_DIGEST_LENGTH];
+
+ /*
+ * Hash the passed-in key to get a smaller key.
+ * The inner context is used since it hasn't been
+ * initialized yet.
+ */
+ PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
+ &sha2_hmac_ctx_tmpl->hc_icontext,
+ key->ck_data, keylen_in_bytes, digested_key);
+ sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, digested_key,
+ sha_digest_len);
+ } else {
+ sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, key->ck_data,
+ keylen_in_bytes);
+ }
+
+ *ctx_template = (crypto_spi_ctx_template_t)sha2_hmac_ctx_tmpl;
+ *ctx_template_size = sizeof (sha2_hmac_ctx_t);
+
+ return (CRYPTO_SUCCESS);
+}
+
+static int
+sha2_free_context(crypto_ctx_t *ctx)
+{
+ uint_t ctx_len;
+
+ if (ctx->cc_provider_private == NULL)
+ return (CRYPTO_SUCCESS);
+
+ /*
+ * We have to free either SHA2 or SHA2-HMAC contexts, which
+ * have different lengths.
+ *
+ * Note: Below is dependent on the mechanism ordering.
+ */
+
+ if (PROV_SHA2_CTX(ctx)->sc_mech_type % 3 == 0)
+ ctx_len = sizeof (sha2_ctx_t);
+ else
+ ctx_len = sizeof (sha2_hmac_ctx_t);
+
+ bzero(ctx->cc_provider_private, ctx_len);
+ kmem_free(ctx->cc_provider_private, ctx_len);
+ ctx->cc_provider_private = NULL;
+
+ return (CRYPTO_SUCCESS);
+}
diff --git a/usr/src/uts/common/sys/sha1.h b/usr/src/uts/common/sys/sha1.h
index ef07d457e0..f81a1ae45c 100644
--- a/usr/src/uts/common/sys/sha1.h
+++ b/usr/src/uts/common/sys/sha1.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1998-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,8 +45,8 @@ typedef struct {
} SHA1_CTX;
void SHA1Init(SHA1_CTX *);
-void SHA1Update(SHA1_CTX *, const uint8_t *, uint32_t);
-void SHA1Final(uint8_t *, SHA1_CTX *);
+void SHA1Update(SHA1_CTX *, const void *, size_t);
+void SHA1Final(void *, SHA1_CTX *);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/sys/sha2.h b/usr/src/uts/common/sys/sha2.h
index 4835b1b536..f057a602de 100644
--- a/usr/src/uts/common/sys/sha2.h
+++ b/usr/src/uts/common/sys/sha2.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,16 +34,6 @@
extern "C" {
#endif
-#define SHA256 0
-#define SHA256_HMAC 1
-#define SHA256_HMAC_GEN 2
-#define SHA384 3
-#define SHA384_HMAC 4
-#define SHA384_HMAC_GEN 5
-#define SHA512 6
-#define SHA512_HMAC 7
-#define SHA512_HMAC_GEN 8
-
#define SHA2_HMAC_MIN_KEY_LEN 8 /* SHA2-HMAC min key length in bits */
#define SHA2_HMAC_MAX_KEY_LEN INT_MAX /* SHA2-HMAC max key length in bits */
@@ -55,8 +44,23 @@ extern "C" {
#define SHA256_HMAC_BLOCK_SIZE 64 /* SHA256-HMAC block size */
#define SHA512_HMAC_BLOCK_SIZE 128 /* SHA512-HMAC block size */
+#define SHA256 0
+#define SHA256_HMAC 1
+#define SHA256_HMAC_GEN 2
+#define SHA384 3
+#define SHA384_HMAC 4
+#define SHA384_HMAC_GEN 5
+#define SHA512 6
+#define SHA512_HMAC 7
+#define SHA512_HMAC_GEN 8
-/* SHA2 context. */
+/*
+ * SHA2 context.
+ * The contents of this structure are a private interface between the
+ * Init/Update/Final calls of the functions defined below.
+ * Callers must never attempt to read or write any of the fields
+ * in this strucutre directly.
+ */
typedef struct {
uint32_t algotype; /* Algorithm Type */
@@ -77,11 +81,61 @@ typedef struct {
} buf_un;
} SHA2_CTX;
+typedef SHA2_CTX SHA256_CTX;
+typedef SHA2_CTX SHA384_CTX;
+typedef SHA2_CTX SHA512_CTX;
+
extern void SHA2Init(uint64_t mech, SHA2_CTX *);
-extern void SHA2Update(SHA2_CTX *, const uint8_t *, uint32_t);
+extern void SHA2Update(SHA2_CTX *, const void *, size_t);
+
+extern void SHA2Final(void *, SHA2_CTX *);
+
+extern void SHA256Init(SHA256_CTX *);
+
+extern void SHA256Update(SHA256_CTX *, const void *, size_t);
+
+extern void SHA256Final(void *, SHA256_CTX *);
+
+extern void SHA384Init(SHA384_CTX *);
+
+extern void SHA384Update(SHA384_CTX *, const void *, size_t);
+
+extern void SHA384Final(void *, SHA384_CTX *);
-extern void SHA2Final(uint8_t *, SHA2_CTX *);
+extern void SHA512Init(SHA512_CTX *);
+
+extern void SHA512Update(SHA512_CTX *, const void *, size_t);
+
+extern void SHA512Final(void *, SHA512_CTX *);
+
+#ifdef _SHA2_IMPL
+/*
+ * The following types/functions are all private to the implementation
+ * of the SHA2 functions and must not be used by consumers of the interface
+ */
+
+/*
+ * List of support mechanisms in this module.
+ *
+ * It is important to note that in the module, division or modulus calculations
+ * are used on the enumerated type to determine which mechanism is being used;
+ * therefore, changing the order or additional mechanisms should be done
+ * carefully
+ */
+typedef enum sha2_mech_type {
+ SHA256_MECH_INFO_TYPE, /* SUN_CKM_SHA256 */
+ SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
+ SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
+ SHA384_MECH_INFO_TYPE, /* SUN_CKM_SHA384 */
+ SHA384_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC */
+ SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */
+ SHA512_MECH_INFO_TYPE, /* SUN_CKM_SHA512 */
+ SHA512_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA512_HMAC */
+ SHA512_HMAC_GEN_MECH_INFO_TYPE /* SUN_CKM_SHA512_HMAC_GENERAL */
+} sha2_mech_type_t;
+
+#endif /* _SHA2_IMPL */
#ifdef __cplusplus
}
diff --git a/usr/src/uts/sun4v/md5/Makefile b/usr/src/uts/sun4v/md5/Makefile
index 0a8289acdf..e99af50999 100644
--- a/usr/src/uts/sun4v/md5/Makefile
+++ b/usr/src/uts/sun4v/md5/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -22,7 +21,7 @@
#
# uts/sun4v/md5/Makefile
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -64,11 +63,6 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOTLINK)
CFLAGS += $(CCVERBOSE)
#
-# watch for ugly -Dsun4u
-#
-CPPFLAGS += -Dsun4u
-
-#
# Override the default -xspace setting
#
sparc_SPACEFLAG = -W0,-Lt -W2,-Rcond_elim