diff options
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 |