aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/crypto
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2017-07-07 17:03:42 +0000
committerCy Schubert <cy@FreeBSD.org>2017-07-07 17:03:42 +0000
commit33a9b234e7087f573ef08cd7318c6497ba08b439 (patch)
treed0ea40ad3bf5463a3c55795977c71bcb7d781b4b /src/lib/crypto
downloadsrc-33a9b234e7087f573ef08cd7318c6497ba08b439.tar.gz
src-33a9b234e7087f573ef08cd7318c6497ba08b439.zip
Import MIT KRB5 1.15.1, which will gracefully replace KTH Heimdal.vendor/krb5/1.15.1
The tarball used in this import is the same tarball used in ports/krb5-115 r435378. Obtained from: http://web.mit.edu/kerberos/dist/ Thanks to: pfg (for all your tireless behind-the-scenes effort)
Notes
Notes: svn path=/vendor-crypto/krb5/dist/; revision=320790 svn path=/vendor-crypto/krb5/1.15.1/; revision=320791; tag=vendor/krb5/1.15.1
Diffstat (limited to 'src/lib/crypto')
-rw-r--r--src/lib/crypto/ISSUES14
-rw-r--r--src/lib/crypto/Makefile.in54
-rw-r--r--src/lib/crypto/builtin/Makefile.in51
-rw-r--r--src/lib/crypto/builtin/aes/Makefile.in62
-rw-r--r--src/lib/crypto/builtin/aes/aes-gen.c326
-rw-r--r--src/lib/crypto/builtin/aes/aes.h98
-rw-r--r--src/lib/crypto/builtin/aes/aes.txt70
-rw-r--r--src/lib/crypto/builtin/aes/aescpp.h55
-rw-r--r--src/lib/crypto/builtin/aes/aescrypp.c488
-rw-r--r--src/lib/crypto/builtin/aes/aescrypt.asm402
-rw-r--r--src/lib/crypto/builtin/aes/aescrypt.c422
-rw-r--r--src/lib/crypto/builtin/aes/aeskey.c370
-rw-r--r--src/lib/crypto/builtin/aes/aeskeypp.c400
-rw-r--r--src/lib/crypto/builtin/aes/aesopt.h852
-rw-r--r--src/lib/crypto/builtin/aes/aessrc.url1
-rw-r--r--src/lib/crypto/builtin/aes/aestab.c493
-rw-r--r--src/lib/crypto/builtin/aes/deps9
-rw-r--r--src/lib/crypto/builtin/aes/iaesx64.s799
-rw-r--r--src/lib/crypto/builtin/aes/iaesx86.s842
-rw-r--r--src/lib/crypto/builtin/camellia/Makefile.in41
-rw-r--r--src/lib/crypto/builtin/camellia/camellia-gen.c333
-rw-r--r--src/lib/crypto/builtin/camellia/camellia.c1539
-rw-r--r--src/lib/crypto/builtin/camellia/camellia.h125
-rw-r--r--src/lib/crypto/builtin/camellia/deps5
-rw-r--r--src/lib/crypto/builtin/crypto_mod.h39
-rw-r--r--src/lib/crypto/builtin/deps36
-rw-r--r--src/lib/crypto/builtin/des/ISSUES13
-rw-r--r--src/lib/crypto/builtin/des/Makefile.in80
-rw-r--r--src/lib/crypto/builtin/des/d3_aead.c133
-rw-r--r--src/lib/crypto/builtin/des/d3_kysched.c51
-rw-r--r--src/lib/crypto/builtin/des/deps148
-rw-r--r--src/lib/crypto/builtin/des/des_int.h286
-rw-r--r--src/lib/crypto/builtin/des/des_keys.c40
-rw-r--r--src/lib/crypto/builtin/des/destest.c243
-rw-r--r--src/lib/crypto/builtin/des/doc/libdes.doc208
-rw-r--r--src/lib/crypto/builtin/des/f_aead.c173
-rw-r--r--src/lib/crypto/builtin/des/f_cbc.c256
-rw-r--r--src/lib/crypto/builtin/des/f_cksum.c136
-rw-r--r--src/lib/crypto/builtin/des/f_parity.c56
-rw-r--r--src/lib/crypto/builtin/des/f_sched.c359
-rw-r--r--src/lib/crypto/builtin/des/f_tables.c370
-rw-r--r--src/lib/crypto/builtin/des/f_tables.h285
-rw-r--r--src/lib/crypto/builtin/des/key_sched.c62
-rw-r--r--src/lib/crypto/builtin/des/keytest.data171
-rw-r--r--src/lib/crypto/builtin/des/t_verify.c419
-rw-r--r--src/lib/crypto/builtin/des/weak_key.c86
-rw-r--r--src/lib/crypto/builtin/enc_provider/Makefile.in45
-rw-r--r--src/lib/crypto/builtin/enc_provider/aes.c406
-rw-r--r--src/lib/crypto/builtin/enc_provider/camellia.c315
-rw-r--r--src/lib/crypto/builtin/enc_provider/deps64
-rw-r--r--src/lib/crypto/builtin/enc_provider/des.c120
-rw-r--r--src/lib/crypto/builtin/enc_provider/des3.c105
-rw-r--r--src/lib/crypto/builtin/enc_provider/rc4.c190
-rw-r--r--src/lib/crypto/builtin/hash_provider/Makefile.in40
-rw-r--r--src/lib/crypto/builtin/hash_provider/deps68
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_crc32.c56
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_md4.c61
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_md5.c61
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_sha1.c62
-rw-r--r--src/lib/crypto/builtin/hash_provider/hash_sha2.c88
-rw-r--r--src/lib/crypto/builtin/hmac.c120
-rw-r--r--src/lib/crypto/builtin/init.c38
-rw-r--r--src/lib/crypto/builtin/md4/ISSUES4
-rw-r--r--src/lib/crypto/builtin/md4/Makefile.in33
-rw-r--r--src/lib/crypto/builtin/md4/deps13
-rw-r--r--src/lib/crypto/builtin/md4/md4.c243
-rw-r--r--src/lib/crypto/builtin/md4/rsa-md4.h90
-rw-r--r--src/lib/crypto/builtin/md5/ISSUES4
-rw-r--r--src/lib/crypto/builtin/md5/Makefile.in31
-rw-r--r--src/lib/crypto/builtin/md5/deps13
-rw-r--r--src/lib/crypto/builtin/md5/md5.c342
-rw-r--r--src/lib/crypto/builtin/md5/rsa-md5.h59
-rw-r--r--src/lib/crypto/builtin/pbkdf2.c249
-rw-r--r--src/lib/crypto/builtin/sha1/ISSUES8
-rw-r--r--src/lib/crypto/builtin/sha1/Makefile.in44
-rw-r--r--src/lib/crypto/builtin/sha1/deps13
-rw-r--r--src/lib/crypto/builtin/sha1/shs.c382
-rw-r--r--src/lib/crypto/builtin/sha1/shs.h46
-rw-r--r--src/lib/crypto/builtin/sha1/t_shs.c136
-rw-r--r--src/lib/crypto/builtin/sha1/t_shs3.c594
-rw-r--r--src/lib/crypto/builtin/sha2/Makefile.in25
-rw-r--r--src/lib/crypto/builtin/sha2/deps23
-rw-r--r--src/lib/crypto/builtin/sha2/sha2.h78
-rw-r--r--src/lib/crypto/builtin/sha2/sha256.c268
-rw-r--r--src/lib/crypto/builtin/sha2/sha512.c305
-rw-r--r--src/lib/crypto/crypto_tests/CRC.pm156
-rw-r--r--src/lib/crypto/crypto_tests/Makefile.in182
-rw-r--r--src/lib/crypto/crypto_tests/Poly.pm182
-rw-r--r--src/lib/crypto/crypto_tests/aes-test.c144
-rw-r--r--src/lib/crypto/crypto_tests/camellia-expect-vt.txt1036
-rw-r--r--src/lib/crypto/crypto_tests/camellia-test.c142
-rwxr-xr-xsrc/lib/crypto/crypto_tests/crc.pl111
-rw-r--r--src/lib/crypto/crypto_tests/deps259
-rw-r--r--src/lib/crypto/crypto_tests/expect-vk.txt1548
-rw-r--r--src/lib/crypto/crypto_tests/expect-vt.txt1036
-rw-r--r--src/lib/crypto/crypto_tests/t_cf2.c98
-rw-r--r--src/lib/crypto/crypto_tests/t_cf2.comments6
-rw-r--r--src/lib/crypto/crypto_tests/t_cf2.expected7
-rw-r--r--src/lib/crypto/crypto_tests/t_cf2.in35
-rw-r--r--src/lib/crypto/crypto_tests/t_cksum.c179
-rw-r--r--src/lib/crypto/crypto_tests/t_cksums.c269
-rw-r--r--src/lib/crypto/crypto_tests/t_cmac.c147
-rw-r--r--src/lib/crypto/crypto_tests/t_combine.c80
-rw-r--r--src/lib/crypto/crypto_tests/t_crc.c205
-rw-r--r--src/lib/crypto/crypto_tests/t_cts.c178
-rw-r--r--src/lib/crypto/crypto_tests/t_decrypt.c775
-rw-r--r--src/lib/crypto/crypto_tests/t_derive.c379
-rw-r--r--src/lib/crypto/crypto_tests/t_encrypt.c292
-rw-r--r--src/lib/crypto/crypto_tests/t_fork.c117
-rw-r--r--src/lib/crypto/crypto_tests/t_hmac.c278
-rw-r--r--src/lib/crypto/crypto_tests/t_kperf.c123
-rw-r--r--src/lib/crypto/crypto_tests/t_mdcksum.c203
-rw-r--r--src/lib/crypto/crypto_tests/t_mddriver.c256
-rw-r--r--src/lib/crypto/crypto_tests/t_nfold.c160
-rw-r--r--src/lib/crypto/crypto_tests/t_pkcs5.c99
-rw-r--r--src/lib/crypto/crypto_tests/t_prf.c149
-rw-r--r--src/lib/crypto/crypto_tests/t_prng.c90
-rw-r--r--src/lib/crypto/crypto_tests/t_prng.comments14
-rw-r--r--src/lib/crypto/crypto_tests/t_prng.expected4
-rw-r--r--src/lib/crypto/crypto_tests/t_prng.seed25
-rw-r--r--src/lib/crypto/crypto_tests/t_sha2.c145
-rw-r--r--src/lib/crypto/crypto_tests/t_short.c133
-rw-r--r--src/lib/crypto/crypto_tests/t_str2key.c792
-rw-r--r--src/lib/crypto/crypto_tests/test/Readme.txt22
-rw-r--r--src/lib/crypto/crypto_tests/test/cbc_d_m.txt7224
-rw-r--r--src/lib/crypto/crypto_tests/test/cbc_e_m.txt7224
-rw-r--r--src/lib/crypto/crypto_tests/test/ecb_d_m.txt6024
-rw-r--r--src/lib/crypto/crypto_tests/test/ecb_e_m.txt6024
-rw-r--r--src/lib/crypto/crypto_tests/test/ecb_iv.readme19
-rw-r--r--src/lib/crypto/crypto_tests/test/ecb_iv.txt123
-rw-r--r--src/lib/crypto/crypto_tests/test/ecb_tbl.txt1955
-rw-r--r--src/lib/crypto/crypto_tests/test/ecb_vk.txt2334
-rw-r--r--src/lib/crypto/crypto_tests/test/ecb_vt.txt1566
-rw-r--r--src/lib/crypto/crypto_tests/test/katmct.pdfbin0 -> 100812 bytes
-rw-r--r--src/lib/crypto/crypto_tests/vb.txt87
-rw-r--r--src/lib/crypto/crypto_tests/vectors.c458
-rw-r--r--src/lib/crypto/deps1
-rw-r--r--src/lib/crypto/krb/Makefile.in227
-rw-r--r--src/lib/crypto/krb/aead.c223
-rw-r--r--src/lib/crypto/krb/block_size.c42
-rw-r--r--src/lib/crypto/krb/cf2.c176
-rw-r--r--src/lib/crypto/krb/checksum_cbc.c41
-rw-r--r--src/lib/crypto/krb/checksum_confounder.c159
-rw-r--r--src/lib/crypto/krb/checksum_dk_cmac.c59
-rw-r--r--src/lib/crypto/krb/checksum_dk_hmac.c59
-rw-r--r--src/lib/crypto/krb/checksum_etm.c65
-rw-r--r--src/lib/crypto/krb/checksum_hmac_md5.c94
-rw-r--r--src/lib/crypto/krb/checksum_length.c42
-rw-r--r--src/lib/crypto/krb/checksum_unkeyed.c36
-rw-r--r--src/lib/crypto/krb/cksumtype_to_string.c42
-rw-r--r--src/lib/crypto/krb/cksumtypes.c130
-rw-r--r--src/lib/crypto/krb/cmac.c200
-rw-r--r--src/lib/crypto/krb/coll_proof_cksum.c37
-rw-r--r--src/lib/crypto/krb/combine_keys.c230
-rw-r--r--src/lib/crypto/krb/crc32.c165
-rw-r--r--src/lib/crypto/krb/crypto_int.h668
-rw-r--r--src/lib/crypto/krb/crypto_length.c125
-rw-r--r--src/lib/crypto/krb/crypto_libinit.c35
-rw-r--r--src/lib/crypto/krb/decrypt.c101
-rw-r--r--src/lib/crypto/krb/decrypt_iov.c64
-rw-r--r--src/lib/crypto/krb/default_state.c54
-rw-r--r--src/lib/crypto/krb/deps783
-rw-r--r--src/lib/crypto/krb/derive.c354
-rw-r--r--src/lib/crypto/krb/enc_dk_cmac.c182
-rw-r--r--src/lib/crypto/krb/enc_dk_hmac.c269
-rw-r--r--src/lib/crypto/krb/enc_etm.c257
-rw-r--r--src/lib/crypto/krb/enc_old.c181
-rw-r--r--src/lib/crypto/krb/enc_raw.c109
-rw-r--r--src/lib/crypto/krb/enc_rc4.c347
-rw-r--r--src/lib/crypto/krb/encrypt.c94
-rw-r--r--src/lib/crypto/krb/encrypt_iov.c58
-rw-r--r--src/lib/crypto/krb/encrypt_length.c47
-rw-r--r--src/lib/crypto/krb/enctype_util.c133
-rw-r--r--src/lib/crypto/krb/etypes.c194
-rw-r--r--src/lib/crypto/krb/key.c110
-rw-r--r--src/lib/crypto/krb/keyblocks.c108
-rw-r--r--src/lib/crypto/krb/keyed_checksum_types.c82
-rw-r--r--src/lib/crypto/krb/keyed_cksum.c39
-rw-r--r--src/lib/crypto/krb/keylengths.c57
-rw-r--r--src/lib/crypto/krb/make_checksum.c99
-rw-r--r--src/lib/crypto/krb/make_checksum_iov.c94
-rw-r--r--src/lib/crypto/krb/make_random_key.c76
-rw-r--r--src/lib/crypto/krb/mandatory_sumtype.c39
-rw-r--r--src/lib/crypto/krb/nfold.c127
-rw-r--r--src/lib/crypto/krb/old_api_glue.c390
-rw-r--r--src/lib/crypto/krb/prf.c84
-rw-r--r--src/lib/crypto/krb/prf_aes2.c42
-rw-r--r--src/lib/crypto/krb/prf_cmac.c58
-rw-r--r--src/lib/crypto/krb/prf_des.c47
-rw-r--r--src/lib/crypto/krb/prf_dk.c70
-rw-r--r--src/lib/crypto/krb/prf_rc4.c39
-rw-r--r--src/lib/crypto/krb/prng.c134
-rw-r--r--src/lib/crypto/krb/prng_device.c99
-rw-r--r--src/lib/crypto/krb/prng_fortuna.c470
-rw-r--r--src/lib/crypto/krb/prng_os.c72
-rw-r--r--src/lib/crypto/krb/random_to_key.c118
-rw-r--r--src/lib/crypto/krb/s2k_des.c691
-rw-r--r--src/lib/crypto/krb/s2k_pbkdf2.c216
-rw-r--r--src/lib/crypto/krb/s2k_rc4.c37
-rw-r--r--src/lib/crypto/krb/state.c60
-rw-r--r--src/lib/crypto/krb/string_to_cksumtype.c56
-rw-r--r--src/lib/crypto/krb/string_to_key.c74
-rw-r--r--src/lib/crypto/krb/t_fortuna.c179
-rw-r--r--src/lib/crypto/krb/t_fortuna.expected9
-rw-r--r--src/lib/crypto/krb/valid_cksumtype.c39
-rw-r--r--src/lib/crypto/krb/verify_checksum.c98
-rw-r--r--src/lib/crypto/krb/verify_checksum_iov.c101
-rw-r--r--src/lib/crypto/libk5crypto.exports110
-rw-r--r--src/lib/crypto/openssl/Makefile.in49
-rw-r--r--src/lib/crypto/openssl/aes/Makefile.in6
-rw-r--r--src/lib/crypto/openssl/aes/deps1
-rw-r--r--src/lib/crypto/openssl/camellia/Makefile.in6
-rw-r--r--src/lib/crypto/openssl/camellia/deps1
-rw-r--r--src/lib/crypto/openssl/crypto_mod.h54
-rw-r--r--src/lib/crypto/openssl/deps46
-rw-r--r--src/lib/crypto/openssl/des/Makefile.in20
-rw-r--r--src/lib/crypto/openssl/des/deps15
-rw-r--r--src/lib/crypto/openssl/des/des_keys.c40
-rw-r--r--src/lib/crypto/openssl/enc_provider/Makefile.in34
-rw-r--r--src/lib/crypto/openssl/enc_provider/aes.c303
-rw-r--r--src/lib/crypto/openssl/enc_provider/camellia.c359
-rw-r--r--src/lib/crypto/openssl/enc_provider/deps59
-rw-r--r--src/lib/crypto/openssl/enc_provider/des.c218
-rw-r--r--src/lib/crypto/openssl/enc_provider/des3.c184
-rw-r--r--src/lib/crypto/openssl/enc_provider/rc4.c156
-rw-r--r--src/lib/crypto/openssl/hash_provider/Makefile.in24
-rw-r--r--src/lib/crypto/openssl/hash_provider/deps27
-rw-r--r--src/lib/crypto/openssl/hash_provider/hash_crc32.c56
-rw-r--r--src/lib/crypto/openssl/hash_provider/hash_evp.c112
-rw-r--r--src/lib/crypto/openssl/hmac.c164
-rw-r--r--src/lib/crypto/openssl/init.c38
-rw-r--r--src/lib/crypto/openssl/md4/Makefile.in6
-rw-r--r--src/lib/crypto/openssl/md4/deps1
-rw-r--r--src/lib/crypto/openssl/md5/Makefile.in6
-rw-r--r--src/lib/crypto/openssl/md5/deps1
-rw-r--r--src/lib/crypto/openssl/pbkdf2.c53
-rw-r--r--src/lib/crypto/openssl/sha1/Makefile.in6
-rw-r--r--src/lib/crypto/openssl/sha1/deps1
-rw-r--r--src/lib/crypto/openssl/sha2/Makefile.in6
-rw-r--r--src/lib/crypto/openssl/sha2/deps1
-rw-r--r--src/lib/crypto/openssl/sha256.c50
-rw-r--r--src/lib/crypto/openssl/stubs.c69
242 files changed, 71816 insertions, 0 deletions
diff --git a/src/lib/crypto/ISSUES b/src/lib/crypto/ISSUES
new file mode 100644
index 000000000000..b821a00c6cc2
--- /dev/null
+++ b/src/lib/crypto/ISSUES
@@ -0,0 +1,14 @@
+Issues to be addressed for src/lib/crypto: -*- text -*-
+
+
+Many files here and in subdirectories pollute the namespace.
+However, some applications wanting to directly use some of those
+routines will expect those names to be available.
+
+Workaround: Shared library export lists? Define and export internal
+names, and provide wrapper library code or weak functions under the
+polluting names?
+
+
+Some routines assume "int" is big enough to describe all buffers that
+may be supplied.
diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in
new file mode 100644
index 000000000000..c3fcfd7e85fc
--- /dev/null
+++ b/src/lib/crypto/Makefile.in
@@ -0,0 +1,54 @@
+mydir=lib$(S)crypto
+BUILDTOP=$(REL)..$(S)..
+SUBDIRS= krb $(CRYPTO_IMPL) crypto_tests
+
+LIBBASE=k5crypto
+LIBMAJOR=3
+LIBMINOR=1
+LIBINITFUNC=cryptoint_initialize_library
+LIBFINIFUNC=cryptoint_cleanup_library
+RELDIR=crypto
+
+STOBJLISTS=$(CRYPTO_IMPL)/enc_provider/OBJS.ST \
+ $(CRYPTO_IMPL)/hash_provider/OBJS.ST \
+ $(CRYPTO_IMPL)/md4/OBJS.ST $(CRYPTO_IMPL)/md5/OBJS.ST \
+ $(CRYPTO_IMPL)/sha1/OBJS.ST $(CRYPTO_IMPL)/sha2/OBJS.ST \
+ $(CRYPTO_IMPL)/aes/OBJS.ST $(CRYPTO_IMPL)/des/OBJS.ST \
+ $(CRYPTO_IMPL)/camellia/OBJS.ST krb/OBJS.ST \
+ $(CRYPTO_IMPL)/OBJS.ST
+
+SUBDIROBJLISTS=$(CRYPTO_IMPL)/enc_provider/OBJS.ST \
+ $(CRYPTO_IMPL)/hash_provider/OBJS.ST \
+ $(CRYPTO_IMPL)/md4/OBJS.ST $(CRYPTO_IMPL)/md5/OBJS.ST \
+ $(CRYPTO_IMPL)/sha1/OBJS.ST $(CRYPTO_IMPL)/sha2/OBJS.ST \
+ $(CRYPTO_IMPL)/aes/OBJS.ST $(CRYPTO_IMPL)/des/OBJS.ST \
+ $(CRYPTO_IMPL)/camellia/OBJS.ST krb/OBJS.ST \
+ $(CRYPTO_IMPL)/OBJS.ST
+
+# No dependencies. Record places to find this shared object if the target
+# link editor and loader support it.
+DEPLIBS=
+CRYPTO_IMPL_LIBS=@CRYPTO_IMPL_LIBS@
+SHLIB_EXPLIBS= $(SUPPORT_LIB) $(CRYPTO_IMPL_LIBS) $(LIBS)
+SHLIB_EXPDEPLIBS= $(SUPPORT_DEPLIB)
+SHLIB_LDFLAGS= $(LDFLAGS) @SHLIB_RPATH_DIRS@
+
+##DOS##LIBNAME=$(OUTPRE)crypto.lib
+##DOS##OBJFILEDEP=$(OUTPRE)krb.lst $(OUTPRE)aes.lst $(OUTPRE)enc_provider.lst $(OUTPRE)des.lst $(OUTPRE)md5.lst $(OUTPRE)camellia.lst $(OUTPRE)md4.lst $(OUTPRE)hash_provider.lst $(OUTPRE)sha2.lst $(OUTPRE)sha1.lst $(OUTPRE)builtin.lst
+##DOS##OBJFILELIST=@$(OUTPRE)krb.lst @$(OUTPRE)aes.lst @$(OUTPRE)enc_provider.lst @$(OUTPRE)des.lst @$(OUTPRE)md5.lst @$(OUTPRE)camellia.lst @$(OUTPRE)md4.lst @$(OUTPRE)hash_provider.lst @$(OUTPRE)sha2.lst @$(OUTPRE)sha1.lst @$(OUTPRE)builtin.lst
+
+all-unix: all-liblinks
+install-unix: install-libs
+
+
+# all-unix:
+# install-unix:
+
+libcrypto.lib:
+ libdir crypto.lib
+
+clean-unix:: clean-liblinks clean-libs clean-libobjs
+
+@lib_frag@
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/Makefile.in b/src/lib/crypto/builtin/Makefile.in
new file mode 100644
index 000000000000..baf5d974f5b4
--- /dev/null
+++ b/src/lib/crypto/builtin/Makefile.in
@@ -0,0 +1,51 @@
+mydir=lib$(S)crypto$(S)builtin
+BUILDTOP=$(REL)..$(S)..$(S)..
+SUBDIRS=camellia des aes md4 md5 sha1 sha2 enc_provider hash_provider
+LOCALINCLUDES = -I$(srcdir)/../krb -I$(srcdir)
+
+##DOS##BUILDTOP = ..\..\..
+##DOS##PREFIXDIR = builtin
+##DOS##OBJFILE = ..\$(OUTPRE)builtin.lst
+
+STLIBOBJS=\
+ hmac.o \
+ init.o \
+ pbkdf2.o
+
+OBJS=\
+ $(OUTPRE)hmac.$(OBJEXT) \
+ $(OUTPRE)init.$(OBJEXT) \
+ $(OUTPRE)pbkdf2.$(OBJEXT)
+
+SRCS=\
+ $(srcdir)/hmac.c \
+ $(srcdir)/init.c \
+ $(srcdir)/pbkdf2.c
+
+STOBJLISTS= des/OBJS.ST md4/OBJS.ST \
+ md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \
+ enc_provider/OBJS.ST \
+ hash_provider/OBJS.ST \
+ aes/OBJS.ST \
+ camellia/OBJS.ST \
+ OBJS.ST
+
+SUBDIROBJLISTS= des/OBJS.ST md4/OBJS.ST \
+ md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \
+ enc_provider/OBJS.ST \
+ hash_provider/OBJS.ST \
+ aes/OBJS.ST \
+ camellia/OBJS.ST
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix: all-libobjs
+includes: depend
+
+depend: $(SRCS)
+
+clean-unix:: clean-libobjs
+
+@lib_frag@
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/aes/Makefile.in b/src/lib/crypto/builtin/aes/Makefile.in
new file mode 100644
index 000000000000..915994b0f5cf
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/Makefile.in
@@ -0,0 +1,62 @@
+mydir=lib$(S)crypto$(S)builtin$(S)aes
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR = builtin\aes
+##DOS##OBJFILE = ..\..\$(OUTPRE)aes.lst
+
+YASM=@YASM@
+AESNI_OBJ=@AESNI_OBJ@
+AESNI_FLAGS=@AESNI_FLAGS@
+
+STLIBOBJS=\
+ aescrypt.o \
+ aestab.o \
+ aeskey.o \
+ @AESNI_OBJ@
+
+OBJS=\
+ $(OUTPRE)aescrypt.$(OBJEXT) \
+ $(OUTPRE)aestab.$(OBJEXT) \
+ $(OUTPRE)aeskey.$(OBJEXT)
+
+SRCS=\
+ $(srcdir)/aescrypt.c \
+ $(srcdir)/aestab.c \
+ $(srcdir)/aeskey.c \
+
+GEN_OBJS=\
+ $(OUTPRE)aescrypt.$(OBJEXT) \
+ $(OUTPRE)aestab.$(OBJEXT) \
+ $(OUTPRE)aeskey.$(OBJEXT)
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix: all-libobjs # aes-gen
+
+iaesx64@SHOBJEXT@: $(srcdir)/iaesx64.s
+ $(YASM) $(AESNI_FLAGS) -o $@ $(srcdir)/iaesx64.s
+
+iaesx86@SHOBJEXT@: $(srcdir)/iaesx86.s
+ $(YASM) $(AESNI_FLAGS) -o $@ $(srcdir)/iaesx86.s
+
+includes: depend
+
+depend: $(SRCS)
+
+aes-gen: aes-gen.o $(GEN_OBJS)
+ $(CC_LINK) -o aes-gen aes-gen.o $(GEN_OBJS)
+
+run-aes-gen: aes-gen
+ ./aes-gen > kresults.out
+
+check: run-aes-gen
+
+
+clean-unix:: clean-libobjs
+
+clean:
+ -$(RM) aes-gen aes-gen.o kresults.out
+
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/aes/aes-gen.c b/src/lib/crypto/builtin/aes/aes-gen.c
new file mode 100644
index 000000000000..573de52b2c36
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aes-gen.c
@@ -0,0 +1,326 @@
+/*
+ * To be compiled against the AES code from:
+ * http://fp.gladman.plus.com/cryptography_technology/rijndael/index.htm
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "aes.h"
+
+#define B 16U
+unsigned char key[16];
+unsigned char test_case_len[] = { B+1, 2*B-1, 2*B, 2*B+1, 3*B-1, 3*B, 4*B, };
+#define NTESTS (sizeof(test_case_len))
+struct {
+ unsigned char ivec[16];
+ unsigned char input[4*16];
+ unsigned char output[4*16];
+} test_case[NTESTS];
+aes_ctx ctx, dctx;
+
+static void init ()
+{
+ unsigned int i, j, r;
+
+ srand(42);
+ for (i = 0; i < 16; i++)
+ key[i] = 0xff & rand();
+ memset(test_case, 0, sizeof(test_case));
+ for (i = 0; i < NTESTS; i++)
+ for (j = 0; j < test_case_len[i]; j++) {
+ test_case[i].input[j] = 0xff & rand();
+ }
+
+ r = aes_enc_key (key, sizeof(key), &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ r = aes_dec_key (key, sizeof(key), &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+}
+
+static void hexdump(const unsigned char *ptr, size_t len)
+{
+ size_t i;
+ for (i = 0; i < len; i++)
+ printf ("%s%02X", (i % 16 == 0) ? "\n " : " ", ptr[i]);
+}
+
+static void fips_test ()
+{
+ static const unsigned char fipskey[16] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ };
+ static const unsigned char input[16] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+ };
+ static const unsigned char expected[16] = {
+ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+ 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
+ };
+ unsigned char output[16];
+ unsigned char tmp[16];
+ aes_ctx fipsctx;
+ int r;
+
+ printf ("FIPS test:\nkey:");
+ hexdump (fipskey, 16);
+ printf ("\ninput:");
+ hexdump (input, 16);
+ r = aes_enc_key (fipskey, sizeof(fipskey), &fipsctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ r = aes_enc_blk (input, output, &fipsctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ printf ("\noutput:");
+ hexdump (output, 16);
+ printf ("\n");
+ if (memcmp(expected, output, 16))
+ fprintf(stderr, "wrong results!!!\n"), exit (1);
+ r = aes_dec_key (fipskey, sizeof(fipskey), &fipsctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ r = aes_dec_blk (output, tmp, &fipsctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ if (memcmp(input, tmp, 16))
+ fprintf(stderr, "decryption failed!!\n"), exit(1);
+ printf ("ok.\n\n");
+}
+
+static void
+xor (unsigned char *out, const unsigned char *a, const unsigned char *b)
+{
+ unsigned int i;
+ for (i = 0; i < B; i++)
+ out[i] = a[i] ^ b[i];
+}
+
+static void
+ecb_enc (unsigned char *out, unsigned char *in, unsigned int len)
+{
+ unsigned int i, r;
+ for (i = 0; i < len; i += 16) {
+ r = aes_enc_blk (in + i, out + i, &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ }
+ if (i != len) abort ();
+}
+
+static void
+ecb_dec (unsigned char *out, unsigned char *in, unsigned int len)
+{
+ unsigned int i, r;
+ for (i = 0; i < len; i += 16) {
+ r = aes_dec_blk (in + i, out + i, &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ }
+ if (i != len) abort ();
+}
+
+#define D(X) (printf("%s %d: %s=",__FUNCTION__,__LINE__, #X),hexdump(X,B),printf("\n"))
+
+#undef D
+#define D(X)
+
+static void
+cbc_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
+ unsigned int len)
+{
+ unsigned int i, r;
+ unsigned char tmp[B];
+ D(iv);
+ memcpy (tmp, iv, B);
+ for (i = 0; i < len; i += B) {
+ D(in+i);
+ xor (tmp, tmp, in + i);
+ D(tmp);
+ r = aes_enc_blk (tmp, out + i, &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ memcpy (tmp, out + i, B);
+ D(out+i);
+ }
+ if (i != len) abort ();
+}
+
+static void
+cbc_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
+ unsigned int len)
+{
+ unsigned int i, r;
+ unsigned char tmp[B];
+ memcpy (tmp, iv, B);
+ for (i = 0; i < len; i += B) {
+ r = aes_dec_blk (in + i, tmp, &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ xor (tmp, tmp, iv);
+ iv = in + i;
+ memcpy (out + i, tmp, B);
+ }
+ if (i != len) abort ();
+}
+
+static void
+cts_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
+ unsigned int len)
+{
+ int r;
+ unsigned int len2;
+ unsigned char pn1[B], pn[B], cn[B], cn1[B];
+
+ if (len < B + 1) abort ();
+ len2 = (len - B - 1) & ~(B-1);
+ cbc_enc (out, in, iv, len2);
+ out += len2;
+ in += len2;
+ len -= len2;
+ if (len2)
+ iv = out - B;
+ if (len <= B || len > 2 * B)
+ abort ();
+ printf ("(did CBC mode for %d)\n", len2);
+
+ D(in);
+ xor (pn1, in, iv);
+ D(pn1);
+ r = aes_enc_blk (pn1, cn, &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ D(cn);
+ memset (pn, 0, sizeof(pn));
+ memcpy (pn, in+B, len-B);
+ D(pn);
+ xor (pn, pn, cn);
+ D(pn);
+ r = aes_enc_blk (pn, cn1, &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ D(cn1);
+ memcpy(out, cn1, B);
+ memcpy(out+B, cn, len-B);
+}
+
+static void
+cts_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
+ unsigned int len)
+{
+ int r;
+ unsigned int len2;
+ unsigned char pn1[B], pn[B], cn[B], cn1[B];
+
+ if (len < B + 1) abort ();
+ len2 = (len - B - 1) & ~(B-1);
+ cbc_dec (out, in, iv, len2);
+ out += len2;
+ in += len2;
+ len -= len2;
+ if (len2)
+ iv = in - B;
+ if (len <= B || len > 2 * B)
+ abort ();
+
+ memcpy (cn1, in, B);
+ r = aes_dec_blk (cn1, pn, &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ memset (cn, 0, sizeof(cn));
+ memcpy (cn, in+B, len-B);
+ xor (pn, pn, cn);
+ memcpy (cn+len-B, pn+len-B, 2*B-len);
+ r = aes_dec_blk (cn, pn1, &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ xor (pn1, pn1, iv);
+ memcpy(out, pn1, B);
+ memcpy(out+B, pn, len-B);
+}
+
+static void ecb_test ()
+{
+ unsigned int testno;
+ unsigned char tmp[4*B];
+
+ printf ("ECB tests:\n");
+ printf ("key:");
+ hexdump (key, sizeof(key));
+ for (testno = 0; testno < NTESTS; testno++) {
+ unsigned len = (test_case_len[testno] + 15) & ~15;
+ printf ("\ntest %d - %d bytes\n", testno, len);
+ printf ("input:");
+ hexdump (test_case[testno].input, len);
+ printf ("\n");
+ ecb_enc (test_case[testno].output, test_case[testno].input, len);
+ printf ("output:");
+ hexdump (test_case[testno].output, len);
+ printf ("\n");
+ ecb_dec (tmp, test_case[testno].output, len);
+ if (memcmp (tmp, test_case[testno].input, len)) {
+ printf ("ecb decrypt failed!!");
+ hexdump (tmp, len);
+ printf ("\n");
+ exit (1);
+ }
+ }
+ printf ("\n");
+}
+
+unsigned char ivec[16] = { 0 };
+
+static void cbc_test ()
+{
+ unsigned int testno;
+ unsigned char tmp[4*B];
+
+ printf ("CBC tests:\n");
+ printf ("initial vector:");
+ hexdump (ivec, sizeof(ivec));
+ for (testno = 0; testno < NTESTS; testno++) {
+ unsigned len = (test_case_len[testno] + 15) & ~15;
+ printf ("\ntest %d - %d bytes\n", testno, len);
+ printf ("input:");
+ hexdump (test_case[testno].input, len);
+ printf ("\n");
+ cbc_enc (test_case[testno].output, test_case[testno].input, ivec, len);
+ printf ("output:");
+ hexdump (test_case[testno].output, len);
+ printf ("\n");
+ cbc_dec (tmp, test_case[testno].output, ivec, len);
+ if (memcmp (tmp, test_case[testno].input, len)) {
+ printf("cbc decrypt failed!!");
+ hexdump (tmp, len);
+ printf ("\n");
+ exit(1);
+ }
+ }
+ printf ("\n");
+}
+
+static void cts_test ()
+{
+ unsigned int testno;
+ unsigned char tmp[4*B];
+
+ printf ("CTS tests:\n");
+ printf ("initial vector:");
+ hexdump (ivec, sizeof(ivec));
+ for (testno = 0; testno < NTESTS; testno++) {
+ unsigned int len = test_case_len[testno];
+ printf ("\ntest %d - %d bytes\n", testno, len);
+ printf ("input:");
+ hexdump (test_case[testno].input, len);
+ printf ("\n");
+ cts_enc (test_case[testno].output, test_case[testno].input, ivec, len);
+ printf ("output:");
+ hexdump (test_case[testno].output, len);
+ printf ("\n");
+ cts_dec (tmp, test_case[testno].output, ivec, len);
+ if (memcmp (tmp, test_case[testno].input, len))
+ fprintf (stderr, "cts decrypt failed!!\n"), exit(1);
+ }
+ printf ("\n");
+}
+
+int main ()
+{
+ init ();
+ fips_test ();
+
+ ecb_test();
+ cbc_test();
+ cts_test();
+
+ return 0;
+}
diff --git a/src/lib/crypto/builtin/aes/aes.h b/src/lib/crypto/builtin/aes/aes.h
new file mode 100644
index 000000000000..8f6f426b9218
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aes.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ * built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explcit or implied warranties
+ * in respect of any properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ */
+
+/*
+ * Issue Date: 21/01/2002
+ *
+ * This file contains the definitions required to use AES (Rijndael) in C.
+ */
+
+#ifndef _AES_H
+#define _AES_H
+
+#include <stdint.h>
+
+/* BLOCK_SIZE is in BYTES: 16, 24, 32 or undefined for aes.c and 16, 20,
+ 24, 28, 32 or undefined for aespp.c. When left undefined a slower
+ version that provides variable block length is compiled.
+*/
+
+#define BLOCK_SIZE 16
+
+/* key schedule length (in 32-bit words) */
+
+#if !defined(BLOCK_SIZE)
+#define KS_LENGTH 128
+#else
+#define KS_LENGTH 4 * BLOCK_SIZE
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef uint16_t aes_fret; /* type for function return value */
+#define aes_bad 0 /* bad function return value */
+#define aes_good 1 /* good function return value */
+#ifndef AES_DLL /* implement normal or DLL functions */
+#define aes_rval aes_fret
+#else
+#define aes_rval aes_fret __declspec(dllexport) _stdcall
+#endif
+
+typedef struct /* the AES context for encryption */
+{ uint32_t k_sch[KS_LENGTH]; /* the encryption key schedule */
+ uint32_t n_rnd; /* the number of cipher rounds */
+ uint32_t n_blk; /* the number of bytes in the state */
+} aes_ctx;
+
+/* for Kerberos 5 tree -- hide names! */
+#define aes_blk_len krb5int_aes_blk_len
+#define aes_enc_key krb5int_aes_enc_key
+#define aes_enc_blk krb5int_aes_enc_blk
+#define aes_dec_key krb5int_aes_dec_key
+#define aes_dec_blk krb5int_aes_dec_blk
+#define fl_tab krb5int_fl_tab
+#define ft_tab krb5int_ft_tab
+#define il_tab krb5int_il_tab
+#define im_tab krb5int_im_tab
+#define it_tab krb5int_it_tab
+#define rcon_tab krb5int_rcon_tab
+
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/aes.txt b/src/lib/crypto/builtin/aes/aes.txt
new file mode 100644
index 000000000000..b644b5eb401f
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aes.txt
@@ -0,0 +1,70 @@
+
+An AES (Rijndael) Implementation in C/C++ (as specified in FIPS-197)
+--------------------------------------------------------------------
+
+The source code files are as follows:
+
+1. aes.h: the header file required to use AES in C
+2. aescpp.h the header file required to use AES in C++
+3. aescrypt.c the main C source code file for encryption and decryption
+4. aeskey.c the main C source code file for the key schedule
+5. aestab.c the main file for the AES tables
+6. aesopt.h the file for common code and for setting build options
+7. aescrypt.asm a faster alternative to 3 above in assembler (using NASM)
+8. uitypes.h a file for defining fixed length unsigned integer types
+9. aescrypp.c an alternative to 3 for all Rijndael block and key sizes
+10.aeskeypp.c an alternative to 4 for all Rijndael block and key sizes
+11.aesxam.c an example of AES use
+
+Source files 9 and 10 are much slower than 4 and 5 for normal use and
+should not be used unless support for 20 and 28 byte blocks and keys
+is necessary. Files 4 and 5 provide support for block and key sizes
+of 16, 24 and 32 bytes (fixed or variable) but the assemler code in
+file 7 only supports the 16 byte AES block length. It does, however,
+offer the three key sizes when used with file 4. The use of files 4
+and 5 (or 9 and 10) with variable block size should be avoided since
+the code is much faster when the block size is fixed.
+
+The VC++ AES Development Project
+--------------------------------
+
+The VC++ SOlution contains the following sub-projects
+
+1. aes_asm this project tests the assembler code implementation
+2. aes_dll this project builds the DLL version
+3. aes_gav this project re-creates the test vector files and
+ optionally checks them against a reference set
+4. aes_rav this project checks the values produced by the code
+ against the values in the test vector files
+5. aes_tmr this project measures the speed of the code
+6. aes_tst this project is set up to test the extended version
+ of Rijndael with block and key sizes of 16, 20, 24,
+ 28 and 32 bytes
+7. aes_xam this project builds the example of AES use in a
+ simple file encryption program
+
+Note that the paths for the various directories have to be set up in
+aestst.h
+
+The AES and Rijndael Test Vector Files
+--------------------------------------
+
+These files fall in the following groups (where <nn> is a two digit
+number):
+
+1. ecbvk<nn>.txt ECB vectors with variable key
+2. ecbvt<nn>.txt ECB vectors with variable text
+3. ecbnk<nn>.txt new ECB vectors with variable key
+4. ecbnt<nn>.txt new ECB vectors with variable text
+5. ecbme<nn>.txt ECB monte carlo encryption test vectors
+6. ecbmd<nn>.txt ECB monte carlo decryption test vectors
+7. cbcme<nn>.txt CBC monte carlo encryption test vectors
+8. cbcmd<nn>.txt CBC monte carlo decryption test vectors
+
+The first digit of the numeric suffix on the filename gives the
+block size in 32bit units and the second numeric digit gives the
+key size. For example, the file ecbvk44.txt provides the test
+vectors for ECB encryption with a 128 bit block size and a 128
+bit key size.
+
+ Brian Gladman <brg@gladman.uk.net> \ No newline at end of file
diff --git a/src/lib/crypto/builtin/aes/aescpp.h b/src/lib/crypto/builtin/aes/aescpp.h
new file mode 100644
index 000000000000..d556224e47d6
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aescpp.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ * All rights reserved.
+ *
+ * TERMS
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted subject to the following conditions:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The copyright holder's name must not be used to endorse or promote
+ * any products derived from this software without his specific prior
+ * written permission.
+ *
+ * This software is provided 'as is' with no express or implied warranties
+ * of correctness or fitness for purpose.
+ */
+
+/*
+ * Issue Date: 21/01/2002
+ *
+ * This file contains the definitions required to use AES (Rijndael) in C++.
+ */
+
+#ifndef _AESCPP_H
+#define _AESCPP_H
+
+#include "aes.h"
+
+class AESclass
+{ aes_ctx cx[1];
+public:
+#if defined(BLOCK_SIZE)
+ AESclass() { cx->n_blk = BLOCK_SIZE; cx->n_rnd = 0; }
+#else
+ AESclass(unsigned int blen = 16) { cx->n_blk = blen; cx->n_rnd = 0; }
+#endif
+ aes_rval blk_len(unsigned int blen) { return aes_blk_len(blen, cx); }
+ aes_rval enc_key(const unsigned char in_key[], unsigned int klen)
+ { return aes_enc_key(in_key, klen, cx); }
+ aes_rval dec_key(const unsigned char in_key[], unsigned int klen)
+ { return aes_dec_key(in_key, klen, cx); }
+ aes_rval enc_blk(const unsigned char in_blk[], unsigned char out_blk[])
+ { return aes_enc_blk(in_blk, out_blk, cx); }
+ aes_rval dec_blk(const unsigned char in_blk[], unsigned char out_blk[])
+ { return aes_dec_blk(in_blk, out_blk, cx); }
+};
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/aescrypp.c b/src/lib/crypto/builtin/aes/aescrypp.c
new file mode 100644
index 000000000000..1f1cf638e028
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aescrypp.c
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ * built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explcit or implied warranties
+ * in respect of any properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ */
+
+/*
+ * Issue Date: 21/01/2002
+ *
+ * This file contains the code for implementing encryption and decryption
+ * for AES (Rijndael) for block and key sizes of 16, 20, 24, 28 and 32 bytes.
+ * It can optionally be replaced by code written in assembler using NASM.
+ */
+
+#include "aesopt.h"
+
+#define unused 77 /* Sunset Strip */
+
+#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
+
+#if BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y,x) x[4],y[4]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
+ /*
+ the following defines prevent the compiler requiring the declaration
+ of generated but unused variables in the fwd_var and inv_var macros
+ */
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
+
+#elif BLOCK_SIZE == 20
+
+#if defined(ARRAYS)
+#define locals(y,x) x[5],y[5]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,y##0,y##1,y##2,y##3,y##4
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); s(y,4) = s(x,4);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); si(y,x,k,4)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); so(y,x,4)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); rm(y,x,k,4)
+
+#elif BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y,x) x[6],y[6]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
+ y##0,y##1,y##2,y##3,y##4,y##5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
+ so(y,x,3); so(y,x,4); so(y,x,5)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
+
+#elif BLOCK_SIZE == 28
+
+#if defined(ARRAYS)
+#define locals(y,x) x[7],y[7]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6 \
+ y##0,y##1,y##2,y##3,y##4,y##5,y##6
+#define b07 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5);; s(y,6) = s(x,6);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5); si(y,x,k,6)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
+ so(y,x,3); so(y,x,4); so(y,x,5); so(y,x,6)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6)
+#else
+
+#if defined(ARRAYS)
+#define locals(y,x) x[8],y[8]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
+ s(y,6) = s(x,6); s(y,7) = s(x,7);
+
+#if BLOCK_SIZE == 32
+
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
+#else
+
+#define state_in(y,x,k) \
+switch(nc) \
+{ case 8: si(y,x,k,7); \
+ case 7: si(y,x,k,6); \
+ case 6: si(y,x,k,5); \
+ case 5: si(y,x,k,4); \
+ case 4: si(y,x,k,3); si(y,x,k,2); \
+ si(y,x,k,1); si(y,x,k,0); \
+}
+
+#define state_out(y,x) \
+switch(nc) \
+{ case 8: so(y,x,7); \
+ case 7: so(y,x,6); \
+ case 6: so(y,x,5); \
+ case 5: so(y,x,4); \
+ case 4: so(y,x,3); so(y,x,2); \
+ so(y,x,1); so(y,x,0); \
+}
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 7: rm(y,x,k,6); rm(y,x,k,5); \
+ rm(y,x,k,4); rm(y,x,k,3); \
+ rm(y,x,k,2); rm(y,x,k,1); \
+ rm(y,x,k,0); \
+ break; \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 5: rm(y,x,k,4); rm(y,x,k,3); \
+ rm(y,x,k,2); rm(y,x,k,1); \
+ rm(y,x,k,0); \
+ break; \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+}
+#else
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); \
+ case 7: rm(y,x,k,6); \
+ case 6: rm(y,x,k,5); \
+ case 5: rm(y,x,k,4); \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+}
+
+#endif
+
+#endif
+#endif
+
+#if defined(ENCRYPTION)
+
+/* I am grateful to Frank Yellin for the following construction
+ (and that for decryption) which, given the column (c) of the
+ output state variable, gives the input state variables which
+ are needed for each row (r) of the state.
+
+ For the fixed block size options, compilers should reduce these
+ two expressions to fixed variable references. But for variable
+ block size code conditional clauses will sometimes be returned.
+
+ y = output word, x = input word, r = row, c = column for r = 0,
+ 1, 2 and 3 = column accessed for row r.
+*/
+
+#define fwd_var(x,r,c) \
+ ( r==0 ? \
+ ( c==0 ? s(x,0) \
+ : c==1 ? s(x,1) \
+ : c==2 ? s(x,2) \
+ : c==3 ? s(x,3) \
+ : c==4 ? s(x,4) \
+ : c==5 ? s(x,5) \
+ : c==6 ? s(x,6) \
+ : s(x,7)) \
+ : r==1 ? \
+ ( c==0 ? s(x,1) \
+ : c==1 ? s(x,2) \
+ : c==2 ? s(x,3) \
+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
+ : c==4 ? nc==5 ? s(x,0) : s(x,5) \
+ : c==5 ? nc==6 ? s(x,0) : s(x,6) \
+ : c==6 ? nc==7 ? s(x,0) : s(x,7) \
+ : s(x,0)) \
+ : r==2 ? \
+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
+ : c==2 ? nc==8 ? s(x,5) : nc==4 ? s(x,0) : s(x,4) \
+ : c==3 ? nc==8 ? s(x,6) : nc==5 ? s(x,0) : nc==4 ? s(x,1) : s(x,5) \
+ : c==4 ? nc==8 ? s(x,7) : nc==7 ? s(x,6) : nc==6 ? s(x,0) : s(x,1) \
+ : c==5 ? nc==6 ? s(x,1) : s(x,0) \
+ : c==6 ? s(x,1) \
+ : s(x,2)) \
+ : \
+ ( c==0 ? nc>6 ? s(x,4) : s(x,3) \
+ : c==1 ? nc>6 ? s(x,5) : nc==4 ? s(x,0) : s(x,4) \
+ : c==2 ? nc>6 ? s(x,6) : nc==6 ? s(x,5) : nc==5 ? s(x,0) : s(x,1) \
+ : c==3 ? nc==8 ? s(x,7) : nc==5 ? s(x,1) : nc==4 ? s(x,2) : s(x,0) \
+ : c==4 ? nc==8 ? s(x,0) : nc==5 ? s(x,2) : s(x,1) \
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==6 ? nc==8 ? s(x,2) : s(x,3) \
+ : s(x,3)))
+
+#if defined(FT4_SET)
+#undef dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
+#elif defined(FT1_SET)
+#undef dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
+#else
+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
+#endif
+
+#if defined(FL4_SET)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
+#elif defined(FL1_SET)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
+#else
+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
+#endif
+
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{ uint32_t locals(b0, b1);
+ const uint32_t *kp = cx->k_sch;
+ dec_fmvars /* declare variables for fwd_mcol() if needed */
+
+ if(!(cx->n_blk & 1)) return aes_bad;
+
+#if (ENC_UNROLL == FULL)
+
+ state_in((cx->n_rnd & 1 ? b1 : b0), in_blk, kp);
+ kp += (cx->n_rnd - 9) * nc;
+
+ switch(cx->n_rnd)
+ {
+ case 14: round(fwd_rnd, b1, b0, kp - 4 * nc);
+ case 13: round(fwd_rnd, b0, b1, kp - 3 * nc);
+ case 12: round(fwd_rnd, b1, b0, kp - 2 * nc);
+ case 11: round(fwd_rnd, b0, b1, kp - nc);
+ case 10: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc);
+ round(fwd_rnd, b1, b0, kp + 2 * nc);
+ round(fwd_rnd, b0, b1, kp + 3 * nc);
+ round(fwd_rnd, b1, b0, kp + 4 * nc);
+ round(fwd_rnd, b0, b1, kp + 5 * nc);
+ round(fwd_rnd, b1, b0, kp + 6 * nc);
+ round(fwd_rnd, b0, b1, kp + 7 * nc);
+ round(fwd_rnd, b1, b0, kp + 8 * nc);
+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
+ }
+#else
+ { uint32_t rnd;
+
+ state_in(b0, in_blk, kp);
+
+#if (ENC_UNROLL == PARTIAL)
+
+ for(rnd = 0; rnd < (cx->n_rnd - 1) >> 1; ++rnd)
+ {
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+ kp += nc;
+ round(fwd_rnd, b0, b1, kp);
+ }
+
+ if(cx->n_rnd & 1)
+ {
+ l_copy(b1, b0);
+ }
+ else
+ {
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+ }
+#else
+ for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+ {
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+ l_copy(b0, b1);
+ }
+#endif
+ kp += nc;
+ round(fwd_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+ return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION)
+
+#define inv_var(x,r,c) \
+ ( r==0 ? \
+ ( c==0 ? s(x,0) \
+ : c==1 ? s(x,1) \
+ : c==2 ? s(x,2) \
+ : c==3 ? s(x,3) \
+ : c==4 ? s(x,4) \
+ : c==5 ? s(x,5) \
+ : c==6 ? s(x,6) \
+ : s(x,7)) \
+ : r==1 ? \
+ ( c==0 ? nc==8 ? s(x,7) : nc==7 ? s(x,6) : nc==6 ? s(x,5) : nc==5 ? s(x,4) : s(x,3) \
+ : c==1 ? s(x,0) \
+ : c==2 ? s(x,1) \
+ : c==3 ? s(x,2) \
+ : c==4 ? s(x,3) \
+ : c==5 ? s(x,4) \
+ : c==6 ? s(x,5) \
+ : s(x,6)) \
+ : r==2 ? \
+ ( c==0 ? nc>6 ? s(x,5) : nc==6 ? s(x,4) : nc==5 ? s(x,3) : s(x,2) \
+ : c==1 ? nc>6 ? s(x,6) : nc==6 ? s(x,5) : nc==5 ? s(x,4) : s(x,3) \
+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
+ : c==6 ? nc==8 ? s(x,3) : s(x,4) \
+ : s(x,4)) \
+ : \
+ ( c==0 ? nc==8 ? s(x,4) : nc==5 ? s(x,2) : nc==4 ? s(x,1) : s(x,3) \
+ : c==1 ? nc==8 ? s(x,5) : nc==5 ? s(x,3) : nc==4 ? s(x,2) : s(x,4) \
+ : c==2 ? nc==8 ? s(x,6) : nc==5 ? s(x,4) : nc==4 ? s(x,3) : s(x,5) \
+ : c==3 ? nc==8 ? s(x,7) : nc==7 ? s(x,6) : s(x,0) \
+ : c==4 ? nc>6 ? s(x,0) : s(x,1) \
+ : c==5 ? nc==6 ? s(x,2) : s(x,1) \
+ : c==6 ? s(x,2) \
+ : s(x,3)))
+
+#if defined(IT4_SET)
+#undef dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
+#elif defined(IT1_SET)
+#undef dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
+#else
+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
+#endif
+
+#if defined(IL4_SET)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
+#elif defined(IL1_SET)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
+#else
+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
+#endif
+
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{ uint32_t locals(b0, b1);
+ const uint32_t *kp = cx->k_sch + nc * cx->n_rnd;
+ dec_imvars /* declare variables for inv_mcol() if needed */
+
+ if(!(cx->n_blk & 2)) return aes_bad;
+
+#if (DEC_UNROLL == FULL)
+
+ state_in((cx->n_rnd & 1 ? b1 : b0), in_blk, kp);
+ kp = cx->k_sch + 9 * nc;
+
+ switch(cx->n_rnd)
+ {
+ case 14: round(inv_rnd, b1, b0, kp + 4 * nc);
+ case 13: round(inv_rnd, b0, b1, kp + 3 * nc);
+ case 12: round(inv_rnd, b1, b0, kp + 2 * nc);
+ case 11: round(inv_rnd, b0, b1, kp + nc);
+ case 10: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp - nc);
+ round(inv_rnd, b1, b0, kp - 2 * nc);
+ round(inv_rnd, b0, b1, kp - 3 * nc);
+ round(inv_rnd, b1, b0, kp - 4 * nc);
+ round(inv_rnd, b0, b1, kp - 5 * nc);
+ round(inv_rnd, b1, b0, kp - 6 * nc);
+ round(inv_rnd, b0, b1, kp - 7 * nc);
+ round(inv_rnd, b1, b0, kp - 8 * nc);
+ round(inv_lrnd, b0, b1, kp - 9 * nc);
+ }
+#else
+ { uint32_t rnd;
+
+ state_in(b0, in_blk, kp);
+
+#if (DEC_UNROLL == PARTIAL)
+
+ for(rnd = 0; rnd < (cx->n_rnd - 1) >> 1; ++rnd)
+ {
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+ kp -= nc;
+ round(inv_rnd, b0, b1, kp);
+ }
+
+ if(cx->n_rnd & 1)
+ {
+ l_copy(b1, b0);
+ }
+ else
+ {
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+ }
+#else
+ for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+ {
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+ l_copy(b0, b1);
+ }
+#endif
+ kp -= nc;
+ round(inv_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+ return aes_good;
+}
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/aescrypt.asm b/src/lib/crypto/builtin/aes/aescrypt.asm
new file mode 100644
index 000000000000..35a6818b6ec3
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aescrypt.asm
@@ -0,0 +1,402 @@
+
+; -------------------------------------------------------------------------
+; Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+; All rights reserved.
+;
+; LICENSE TERMS
+;
+; The free distribution and use of this software in both source and binary
+; form is allowed (with or without changes) provided that:
+;
+; 1. distributions of this source code include the above copyright
+; notice, this list of conditions and the following disclaimer;
+;
+; 2. distributions in binary form include the above copyright
+; notice, this list of conditions and the following disclaimer
+; in the documentation and/or other associated materials;
+;
+; 3. the copyright holder's name is not used to endorse products
+; built using this software without specific written permission.
+;
+; DISCLAIMER
+;
+; This software is provided 'as is' with no explcit or implied warranties
+; in respect of any properties, including, but not limited to, correctness
+; and fitness for purpose.
+; -------------------------------------------------------------------------
+; Issue Date: 15/01/2002
+
+; An AES (Rijndael) implementation for the Pentium MMX family using the NASM
+; assembler <http://www.web-sites.co.uk/nasm/>. This version only implements
+; the standard AES block length (128 bits, 16 bytes) with the same interface
+; as that used in my C/C++ implementation. This code does not preserve the
+; eax, ecx or edx registers or the artihmetic status flags. However, the ebx,
+; esi, edi, and ebp registers are preserved across calls. Only encryption
+; and decryption are implemented here, the key schedule code being that from
+; compiling aes.c with USE_ASM defined. This code uses VC++ register saving
+; conentions; if it is used with another compiler, its conventions for using
+; and saving registers will need to be checked.
+
+ section .text use32
+
+; aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+; aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+ global _aes_enc_blk
+ global _aes_dec_blk
+
+ extern _ft_tab
+ extern _fl_tab
+ extern _it_tab
+ extern _il_tab
+
+;%define USE_MMX ; include this to use MMX registers for temporary storage
+;%define USE_EMMS ; include this if you make use of floating point operations
+
+%ifdef USE_MMX
+%ifdef USE_EMMS
+%define EMMS_ON
+%endif
+%endif
+
+tlen: equ 1024 ; length of each of 4 'xor' arrays (256 32-bit words)
+
+; offsets to parameters with one register pushed onto stack
+
+in_blk: equ 8 ; input byte array address parameter
+out_blk:equ 12 ; output byte array address parameter
+ctx: equ 16 ; AES context structure
+
+; offsets in context structure
+
+ksch: equ 0 ; encryption key schedule base address
+nrnd: equ 256 ; number of rounds
+nblk: equ 260 ; number of rounds
+
+; register mapping for encrypt and decrypt subroutines
+
+%define r0 eax
+%define r1 ebx
+%define r2 ecx
+%define r3 edx
+%define r4 esi
+%define r5 edi
+%define r6 ebp
+
+%define eaxl al
+%define eaxh ah
+%define ebxl bl
+%define ebxh bh
+%define ecxl cl
+%define ecxh ch
+%define edxl dl
+%define edxh dh
+
+; This macro takes a 32-bit word representing a column and uses
+; each of its four bytes to index into four tables of 256 32-bit
+; words to obtain values that are then xored into the appropriate
+; output registers r0, r1, r4 or r5.
+
+; Parameters:
+; %1 out_state[0]
+; %2 out_state[1]
+; %3 out_state[2]
+; %4 out_state[3]
+; %5 table base address
+; %6 input register for the round (destroyed)
+; %7 scratch register for the round
+
+%macro do_col 7
+
+ movzx %7,%6l
+ xor %1,[4*%7+%5]
+ movzx %7,%6h
+ shr %6,16
+ xor %2,[4*%7+%5+tlen]
+ movzx %7,%6l
+ movzx %6,%6h
+ xor %3,[4*%7+%5+2*tlen]
+ xor %4,[4*%6+%5+3*tlen]
+
+%endmacro
+
+; initialise output registers from the key schedule
+
+%macro do_fcol 8
+
+ mov %1,[%8]
+ movzx %7,%6l
+ mov %2,[%8+12]
+ xor %1,[4*%7+%5]
+ mov %4,[%8+ 4]
+ movzx %7,%6h
+ shr %6,16
+ xor %2,[4*%7+%5+tlen]
+ movzx %7,%6l
+ movzx %6,%6h
+ xor %4,[4*%6+%5+3*tlen]
+ mov %6,%3
+ mov %3,[%8+ 8]
+ xor %3,[4*%7+%5+2*tlen]
+
+%endmacro
+
+; initialise output registers from the key schedule
+
+%macro do_icol 8
+
+ mov %1,[%8]
+ movzx %7,%6l
+ mov %2,[%8+ 4]
+ xor %1,[4*%7+%5]
+ mov %4,[%8+12]
+ movzx %7,%6h
+ shr %6,16
+ xor %2,[4*%7+%5+tlen]
+ movzx %7,%6l
+ movzx %6,%6h
+ xor %4,[4*%6+%5+3*tlen]
+ mov %6,%3
+ mov %3,[%8+ 8]
+ xor %3,[4*%7+%5+2*tlen]
+
+%endmacro
+
+; These macros implement either MMX or stack based local variables
+
+%ifdef USE_MMX
+
+%macro save 2
+ movd mm%1,%2
+%endmacro
+
+%macro restore 2
+ movd %1,mm%2
+%endmacro
+
+%else
+
+%macro save 2
+ mov [esp+4*%1],%2
+%endmacro
+
+%macro restore 2
+ mov %1,[esp+4*%2]
+%endmacro
+
+%endif
+
+; This macro performs a forward encryption cycle. It is entered with
+; the first previous round column values in r0, r1, r4 and r5 and
+; exits with the final values in the same registers, using the MMX
+; registers mm0-mm1 for temporary storage
+
+%macro fwd_rnd 1-2 _ft_tab
+
+; mov current column values into the MMX registers
+
+ mov r2,r0
+ save 0,r1
+ save 1,r5
+
+; compute new column values
+
+ do_fcol r0,r5,r4,r1, %2, r2,r3, %1
+ do_col r4,r1,r0,r5, %2, r2,r3
+ restore r2,0
+ do_col r1,r0,r5,r4, %2, r2,r3
+ restore r2,1
+ do_col r5,r4,r1,r0, %2, r2,r3
+
+%endmacro
+
+; This macro performs an inverse encryption cycle. It is entered with
+; the first previous round column values in r0, r1, r4 and r5 and
+; exits with the final values in the same registers, using the MMX
+; registers mm0-mm1 for temporary storage
+
+%macro inv_rnd 1-2 _it_tab
+
+; mov current column values into the MMX registers
+
+ mov r2,r0
+ save 0,r1
+ save 1,r5
+
+; compute new column values
+
+ do_icol r0,r1,r4,r5, %2, r2,r3, %1
+ do_col r4,r5,r0,r1, %2, r2,r3
+ restore r2,0
+ do_col r1,r4,r5,r0, %2, r2,r3
+ restore r2,1
+ do_col r5,r0,r1,r4, %2, r2,r3
+
+%endmacro
+
+; AES (Rijndael) Encryption Subroutine
+
+_aes_enc_blk:
+ push ebp
+ mov ebp,[esp+ctx] ; pointer to context
+ xor eax,eax
+ test [ebp+nblk],byte 1
+ je .0
+ cmp eax,[ebp+nrnd] ; encryption/decryption flags
+ jne short .1
+.0: pop ebp
+ ret
+
+; CAUTION: the order and the values used in these assigns
+; rely on the register mappings
+
+.1: push ebx
+ mov r2,[esp+in_blk+4]
+ push esi
+ mov r3,[ebp+nrnd] ; number of rounds
+ push edi
+ lea r6,[ebp+ksch] ; key pointer
+
+; input four columns and xor in first round key
+
+ mov r0,[r2]
+ mov r1,[r2+4]
+ mov r4,[r2+8]
+ mov r5,[r2+12]
+ xor r0,[r6]
+ xor r1,[r6+4]
+ xor r4,[r6+8]
+ xor r5,[r6+12]
+
+%ifndef USE_MMX
+ sub esp,8 ; space for register saves on stack
+%endif
+ add r6,16 ; increment to next round key
+ sub r3,10
+ je .4 ; 10 rounds for 128-bit key
+ add r6,32
+ sub r3,2
+ je .3 ; 12 rounds for 128-bit key
+ add r6,32
+
+.2: fwd_rnd r6-64 ; 14 rounds for 128-bit key
+ fwd_rnd r6-48
+.3: fwd_rnd r6-32 ; 12 rounds for 128-bit key
+ fwd_rnd r6-16
+.4: fwd_rnd r6 ; 10 rounds for 128-bit key
+ fwd_rnd r6+ 16
+ fwd_rnd r6+ 32
+ fwd_rnd r6+ 48
+ fwd_rnd r6+ 64
+ fwd_rnd r6+ 80
+ fwd_rnd r6+ 96
+ fwd_rnd r6+112
+ fwd_rnd r6+128
+ fwd_rnd r6+144,_fl_tab ; last round uses a different table
+
+; move final values to the output array. CAUTION: the
+; order of these assigns rely on the register mappings
+
+%ifndef USE_MMX
+ add esp,8
+%endif
+ mov r6,[esp+out_blk+12]
+ mov [r6+12],r5
+ pop edi
+ mov [r6+8],r4
+ pop esi
+ mov [r6+4],r1
+ pop ebx
+ mov [r6],r0
+ pop ebp
+ mov eax,1
+%ifdef EMMS_ON
+ emms
+%endif
+ ret
+
+; AES (Rijndael) Decryption Subroutine
+
+_aes_dec_blk:
+ push ebp
+ mov ebp,[esp+ctx] ; pointer to context
+ xor eax,eax
+ test [ebp+nblk],byte 2
+ je .0
+ cmp eax,[ebp+nrnd] ; encryption/decryption flags
+ jne short .1
+.0: pop ebp
+ ret
+
+; CAUTION: the order and the values used in these assigns
+; rely on the register mappings
+
+.1: push ebx
+ mov r2,[esp+in_blk+4]
+ push esi
+ mov r3,[ebp+nrnd] ; number of rounds
+ push edi
+ lea r6,[ebp+ksch] ; key pointer
+ mov r0,r3
+ shl r0,4
+ add r6,r0
+
+; input four columns and xor in first round key
+
+ mov r0,[r2]
+ mov r1,[r2+4]
+ mov r4,[r2+8]
+ mov r5,[r2+12]
+ xor r0,[r6]
+ xor r1,[r6+4]
+ xor r4,[r6+8]
+ xor r5,[r6+12]
+
+%ifndef USE_MMX
+ sub esp,8 ; space for register saves on stack
+%endif
+ sub r6,16 ; increment to next round key
+ sub r3,10
+ je .4 ; 10 rounds for 128-bit key
+ sub r6,32
+ sub r3,2
+ je .3 ; 12 rounds for 128-bit key
+ sub r6,32
+
+.2: inv_rnd r6+64 ; 14 rounds for 128-bit key
+ inv_rnd r6+48
+.3: inv_rnd r6+32 ; 12 rounds for 128-bit key
+ inv_rnd r6+16
+.4: inv_rnd r6 ; 10 rounds for 128-bit key
+ inv_rnd r6- 16
+ inv_rnd r6- 32
+ inv_rnd r6- 48
+ inv_rnd r6- 64
+ inv_rnd r6- 80
+ inv_rnd r6- 96
+ inv_rnd r6-112
+ inv_rnd r6-128
+ inv_rnd r6-144,_il_tab ; last round uses a different table
+
+; move final values to the output array. CAUTION: the
+; order of these assigns rely on the register mappings
+
+%ifndef USE_MMX
+ add esp,8
+%endif
+ mov r6,[esp+out_blk+12]
+ mov [r6+12],r5
+ pop edi
+ mov [r6+8],r4
+ pop esi
+ mov [r6+4],r1
+ pop ebx
+ mov [r6],r0
+ pop ebp
+ mov eax,1
+%ifdef EMMS_ON
+ emms
+%endif
+ ret
+
+ end
diff --git a/src/lib/crypto/builtin/aes/aescrypt.c b/src/lib/crypto/builtin/aes/aescrypt.c
new file mode 100644
index 000000000000..194f8e54dbe4
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aescrypt.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ * built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explcit or implied warranties
+ * in respect of any properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ */
+
+/*
+ * Issue Date: 21/01/2002
+ *
+ * This file contains the code for implementing encryption and decryption
+ * for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
+ * can optionally be replaced by code written in assembler using NASM.
+*/
+
+#include "aesopt.h"
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+#define unused 77 /* Sunset Strip */
+
+#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
+
+#if BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y,x) x[4],y[4]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
+ /*
+ the following defines prevent the compiler requiring the declaration
+ of generated but unused variables in the fwd_var and inv_var macros
+ */
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
+
+#elif BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y,x) x[6],y[6]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
+ y##0,y##1,y##2,y##3,y##4,y##5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
+ so(y,x,3); so(y,x,4); so(y,x,5)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
+#else
+
+#if defined(ARRAYS)
+#define locals(y,x) x[8],y[8]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
+ s(y,6) = s(x,6); s(y,7) = s(x,7);
+
+#if BLOCK_SIZE == 32
+
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
+#else
+
+#define state_in(y,x,k) \
+switch(nc) \
+{ case 8: si(y,x,k,7); si(y,x,k,6); \
+ case 6: si(y,x,k,5); si(y,x,k,4); \
+ case 4: si(y,x,k,3); si(y,x,k,2); \
+ si(y,x,k,1); si(y,x,k,0); \
+}
+
+#define state_out(y,x) \
+switch(nc) \
+{ case 8: so(y,x,7); so(y,x,6); \
+ case 6: so(y,x,5); so(y,x,4); \
+ case 4: so(y,x,3); so(y,x,2); \
+ so(y,x,1); so(y,x,0); \
+}
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+}
+#else
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+}
+
+#endif
+
+#endif
+#endif
+
+#if defined(ENCRYPTION)
+
+/* I am grateful to Frank Yellin for the following construction
+ (and that for decryption) which, given the column (c) of the
+ output state variable, gives the input state variables which
+ are needed in its computation for each row (r) of the state.
+
+ For the fixed block size options, compilers should be able to
+ reduce this complex expression (and the equivalent one for
+ decryption) to a static variable reference at compile time.
+ But for variable block size code, there will be some limbs on
+ which conditional clauses will be returned.
+*/
+
+/* y = output word, x = input word, r = row, c = column for r = 0,
+ 1, 2 and 3 = column accessed for row r.
+*/
+
+#define fwd_var(x,r,c) \
+ ( r==0 ? \
+ ( c==0 ? s(x,0) \
+ : c==1 ? s(x,1) \
+ : c==2 ? s(x,2) \
+ : c==3 ? s(x,3) \
+ : c==4 ? s(x,4) \
+ : c==5 ? s(x,5) \
+ : c==6 ? s(x,6) \
+ : s(x,7)) \
+ : r==1 ? \
+ ( c==0 ? s(x,1) \
+ : c==1 ? s(x,2) \
+ : c==2 ? s(x,3) \
+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
+ : c==4 ? s(x,5) \
+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
+ : c==6 ? s(x,7) \
+ : s(x,0)) \
+ : r==2 ? \
+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==6 ? s(x,1) \
+ : s(x,2)) \
+ : \
+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==6 ? s(x,2) \
+ : s(x,3)))
+
+#if defined(FT4_SET)
+#undef dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
+#elif defined(FT1_SET)
+#undef dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
+#else
+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
+#endif
+
+#if defined(FL4_SET)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
+#elif defined(FL1_SET)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
+#else
+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
+#endif
+
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{ uint32_t locals(b0, b1);
+ const uint32_t *kp = cx->k_sch;
+ dec_fmvars /* declare variables for fwd_mcol() if needed */
+
+ if(!(cx->n_blk & 1)) return aes_bad;
+
+ state_in(b0, in_blk, kp);
+
+#if (ENC_UNROLL == FULL)
+
+ kp += (cx->n_rnd - 9) * nc;
+
+ switch(cx->n_rnd)
+ {
+ case 14: round(fwd_rnd, b1, b0, kp - 4 * nc);
+ round(fwd_rnd, b0, b1, kp - 3 * nc);
+ case 12: round(fwd_rnd, b1, b0, kp - 2 * nc);
+ round(fwd_rnd, b0, b1, kp - nc);
+ case 10: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc);
+ round(fwd_rnd, b1, b0, kp + 2 * nc);
+ round(fwd_rnd, b0, b1, kp + 3 * nc);
+ round(fwd_rnd, b1, b0, kp + 4 * nc);
+ round(fwd_rnd, b0, b1, kp + 5 * nc);
+ round(fwd_rnd, b1, b0, kp + 6 * nc);
+ round(fwd_rnd, b0, b1, kp + 7 * nc);
+ round(fwd_rnd, b1, b0, kp + 8 * nc);
+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
+ }
+#else
+
+#if (ENC_UNROLL == PARTIAL)
+ { uint32_t rnd;
+ for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+ {
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+ kp += nc;
+ round(fwd_rnd, b0, b1, kp);
+ }
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+#else
+ { uint32_t rnd, *p0 = b0, *p1 = b1, *pt;
+ for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+ {
+ kp += nc;
+ round(fwd_rnd, p1, p0, kp);
+ pt = p0, p0 = p1, p1 = pt;
+ }
+#endif
+ kp += nc;
+ round(fwd_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+ return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION)
+
+#define inv_var(x,r,c) \
+ ( r==0 ? \
+ ( c==0 ? s(x,0) \
+ : c==1 ? s(x,1) \
+ : c==2 ? s(x,2) \
+ : c==3 ? s(x,3) \
+ : c==4 ? s(x,4) \
+ : c==5 ? s(x,5) \
+ : c==6 ? s(x,6) \
+ : s(x,7)) \
+ : r==1 ? \
+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
+ : c==1 ? s(x,0) \
+ : c==2 ? s(x,1) \
+ : c==3 ? s(x,2) \
+ : c==4 ? s(x,3) \
+ : c==5 ? s(x,4) \
+ : c==6 ? s(x,5) \
+ : s(x,6)) \
+ : r==2 ? \
+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
+ : c==6 ? s(x,3) \
+ : s(x,4)) \
+ : \
+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==6 ? s(x,2) \
+ : s(x,3)))
+
+#if defined(IT4_SET)
+#undef dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
+#elif defined(IT1_SET)
+#undef dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
+#else
+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
+#endif
+
+#if defined(IL4_SET)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
+#elif defined(IL1_SET)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
+#else
+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
+#endif
+
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{ uint32_t locals(b0, b1);
+ const uint32_t *kp = cx->k_sch + nc * cx->n_rnd;
+ dec_imvars /* declare variables for inv_mcol() if needed */
+
+ if(!(cx->n_blk & 2)) return aes_bad;
+
+ state_in(b0, in_blk, kp);
+
+#if (DEC_UNROLL == FULL)
+
+ kp = cx->k_sch + 9 * nc;
+ switch(cx->n_rnd)
+ {
+ case 14: round(inv_rnd, b1, b0, kp + 4 * nc);
+ round(inv_rnd, b0, b1, kp + 3 * nc);
+ case 12: round(inv_rnd, b1, b0, kp + 2 * nc);
+ round(inv_rnd, b0, b1, kp + nc );
+ case 10: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp - nc);
+ round(inv_rnd, b1, b0, kp - 2 * nc);
+ round(inv_rnd, b0, b1, kp - 3 * nc);
+ round(inv_rnd, b1, b0, kp - 4 * nc);
+ round(inv_rnd, b0, b1, kp - 5 * nc);
+ round(inv_rnd, b1, b0, kp - 6 * nc);
+ round(inv_rnd, b0, b1, kp - 7 * nc);
+ round(inv_rnd, b1, b0, kp - 8 * nc);
+ round(inv_lrnd, b0, b1, kp - 9 * nc);
+ }
+#else
+
+#if (DEC_UNROLL == PARTIAL)
+ { uint32_t rnd;
+ for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+ {
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+ kp -= nc;
+ round(inv_rnd, b0, b1, kp);
+ }
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+#else
+ { uint32_t rnd, *p0 = b0, *p1 = b1, *pt;
+ for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+ {
+ kp -= nc;
+ round(inv_rnd, p1, p0, kp);
+ pt = p0, p0 = p1, p1 = pt;
+ }
+#endif
+ kp -= nc;
+ round(inv_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+ return aes_good;
+}
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/aeskey.c b/src/lib/crypto/builtin/aes/aeskey.c
new file mode 100644
index 000000000000..8402b50cfedc
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aeskey.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ * built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explcit or implied warranties
+ * in respect of any properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ */
+
+/*
+ * Issue Date: 21/01/2002
+ *
+ * This file contains the code for implementing the key schedule for AES
+ * (Rijndael) for block and key sizes of 16, 24, and 32 bytes.
+ */
+
+#include "aesopt.h"
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+/* Subroutine to set the block size (if variable) in bytes, legal
+ values being 16, 24 and 32.
+*/
+
+#if !defined(BLOCK_SIZE) && defined(SET_BLOCK_LENGTH)
+
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
+{
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+ if((blen & 7) || blen < 16 || blen > 32)
+ {
+ cx->n_blk = 0; return aes_bad;
+ }
+
+ cx->n_blk = blen;
+ return aes_good;
+}
+
+#endif
+
+/* Initialise the key schedule from the user supplied key. The key
+ length is now specified in bytes - 16, 24 or 32 as appropriate.
+ This corresponds to bit lengths of 128, 192 and 256 bits, and
+ to Nk values of 4, 6 and 8 respectively.
+
+ The following macros implement a single cycle in the key
+ schedule generation process. The number of cycles needed
+ for each cx->n_col and nk value is:
+
+ nk = 4 5 6 7 8
+ ------------------------------
+ cx->n_col = 4 10 9 8 7 7
+ cx->n_col = 5 14 11 10 9 9
+ cx->n_col = 6 19 15 12 11 11
+ cx->n_col = 7 21 19 16 13 14
+ cx->n_col = 8 29 23 19 17 14
+*/
+
+#if defined(ENCRYPTION_KEY_SCHEDULE)
+
+#define ke4(k,i) \
+{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
+ k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+}
+#define kel4(k,i) \
+{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
+ k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+}
+
+#define ke6(k,i) \
+{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+ k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+ k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
+}
+#define kel6(k,i) \
+{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+ k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+}
+
+#define ke8(k,i) \
+{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+ k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+ k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
+ k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
+}
+#define kel8(k,i) \
+{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+ k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+}
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{ uint32_t ss[8];
+
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+#if !defined(BLOCK_SIZE)
+ if(!cx->n_blk) cx->n_blk = 16;
+#else
+ cx->n_blk = BLOCK_SIZE;
+#endif
+
+ cx->n_blk = (cx->n_blk & ~3U) | 1;
+
+ cx->k_sch[0] = ss[0] = word_in(in_key );
+ cx->k_sch[1] = ss[1] = word_in(in_key + 4);
+ cx->k_sch[2] = ss[2] = word_in(in_key + 8);
+ cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
+
+ switch(klen)
+ {
+ case 16: ke4(cx->k_sch, 0); ke4(cx->k_sch, 1);
+ ke4(cx->k_sch, 2); ke4(cx->k_sch, 3);
+ ke4(cx->k_sch, 4); ke4(cx->k_sch, 5);
+ ke4(cx->k_sch, 6); ke4(cx->k_sch, 7);
+ ke4(cx->k_sch, 8); kel4(cx->k_sch, 9);
+ cx->n_rnd = 10; break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ ke6(cx->k_sch, 0); ke6(cx->k_sch, 1);
+ ke6(cx->k_sch, 2); ke6(cx->k_sch, 3);
+ ke6(cx->k_sch, 4); ke6(cx->k_sch, 5);
+ ke6(cx->k_sch, 6); kel6(cx->k_sch, 7);
+ cx->n_rnd = 12; break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ ke8(cx->k_sch, 0); ke8(cx->k_sch, 1);
+ ke8(cx->k_sch, 2); ke8(cx->k_sch, 3);
+ ke8(cx->k_sch, 4); ke8(cx->k_sch, 5);
+ kel8(cx->k_sch, 6);
+ cx->n_rnd = 14; break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#else
+ { uint32_t i, l;
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+ l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
+
+ switch(klen)
+ {
+ case 16: for(i = 0; i < l; ++i)
+ ke4(cx->k_sch, i);
+ break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ for(i = 0; i < l; ++i)
+ ke6(cx->k_sch, i);
+ break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ for(i = 0; i < l; ++i)
+ ke8(cx->k_sch, i);
+ break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+ }
+#endif
+
+ return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION_KEY_SCHEDULE)
+
+#if (DEC_ROUND != NO_TABLES)
+#define d_vars dec_imvars
+#define ff(x) inv_mcol(x)
+#else
+#define ff(x) (x)
+#define d_vars
+#endif
+
+#if 1
+#define kdf4(k,i) \
+{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
+ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
+ ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
+ ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
+}
+#define kd4(k,i) \
+{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
+ k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
+ k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
+}
+#define kdl4(k,i) \
+{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
+ k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
+ k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
+}
+#else
+#define kdf4(k,i) \
+{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
+}
+#define kd4(k,i) \
+{ ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \
+ ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
+ ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
+}
+#define kdl4(k,i) \
+{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
+}
+#endif
+
+#define kdf6(k,i) \
+{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
+ ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
+}
+#define kd6(k,i) \
+{ ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \
+ ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
+ ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
+ ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
+ ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
+}
+#define kdl6(k,i) \
+{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
+}
+
+#define kdf8(k,i) \
+{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
+ ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
+ ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
+}
+#define kd8(k,i) \
+{ uint32_t g = ls_box(ss[7],3) ^ rcon_tab[i]; \
+ ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
+ ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
+ g = ls_box(ss[3],0); \
+ ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
+ ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
+ ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
+ ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
+}
+#define kdl8(k,i) \
+{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
+ ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
+}
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{ uint32_t ss[8];
+ d_vars
+
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+#if !defined(BLOCK_SIZE)
+ if(!cx->n_blk) cx->n_blk = 16;
+#else
+ cx->n_blk = BLOCK_SIZE;
+#endif
+
+ cx->n_blk = (cx->n_blk & ~3U) | 2;
+
+ cx->k_sch[0] = ss[0] = word_in(in_key );
+ cx->k_sch[1] = ss[1] = word_in(in_key + 4);
+ cx->k_sch[2] = ss[2] = word_in(in_key + 8);
+ cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
+
+ switch(klen)
+ {
+ case 16: kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1);
+ kd4(cx->k_sch, 2); kd4(cx->k_sch, 3);
+ kd4(cx->k_sch, 4); kd4(cx->k_sch, 5);
+ kd4(cx->k_sch, 6); kd4(cx->k_sch, 7);
+ kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9);
+ cx->n_rnd = 10; break;
+ case 24: ss[4] = word_in(in_key + 16);
+ cx->k_sch[4] = ff(ss[4]);
+ ss[5] = word_in(in_key + 20);
+ cx->k_sch[5] = ff(ss[5]);
+ kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1);
+ kd6(cx->k_sch, 2); kd6(cx->k_sch, 3);
+ kd6(cx->k_sch, 4); kd6(cx->k_sch, 5);
+ kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7);
+ cx->n_rnd = 12; break;
+ case 32: ss[4] = word_in(in_key + 16);
+ cx->k_sch[4] = ff(ss[4]);
+ ss[5] = word_in(in_key + 20);
+ cx->k_sch[5] = ff(ss[5]);
+ ss[6] = word_in(in_key + 24);
+ cx->k_sch[6] = ff(ss[6]);
+ ss[7] = word_in(in_key + 28);
+ cx->k_sch[7] = ff(ss[7]);
+ kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1);
+ kd8(cx->k_sch, 2); kd8(cx->k_sch, 3);
+ kd8(cx->k_sch, 4); kd8(cx->k_sch, 5);
+ kdl8(cx->k_sch, 6);
+ cx->n_rnd = 14; break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#else
+ { uint32_t i, l;
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+ l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
+
+ switch(klen)
+ {
+ case 16:
+ for(i = 0; i < l; ++i)
+ ke4(cx->k_sch, i);
+ break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ for(i = 0; i < l; ++i)
+ ke6(cx->k_sch, i);
+ break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ for(i = 0; i < l; ++i)
+ ke8(cx->k_sch, i);
+ break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#if (DEC_ROUND != NO_TABLES)
+ for(i = nc; i < nc * cx->n_rnd; ++i)
+ cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
+#endif
+ }
+#endif
+
+ return aes_good;
+}
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/aeskeypp.c b/src/lib/crypto/builtin/aes/aeskeypp.c
new file mode 100644
index 000000000000..cd9c5a7a4aa7
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aeskeypp.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ * built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explcit or implied warranties
+ * in respect of any properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ */
+
+/*
+ * Issue Date: 21/01/2002
+ *
+ * This file contains the code for implementing the key schedule for AES
+ * (Rijndael) for block and key sizes of 16, 20, 24, 28 and 32 bytes.
+ */
+
+#include "aesopt.h"
+
+/* Subroutine to set the block size (if variable) in bytes, legal
+ values being 16, 24 and 32.
+*/
+
+#if !defined(BLOCK_SIZE) && defined(SET_BLOCK_LENGTH)
+
+/* Subroutine to set the block size (if variable) in bytes, legal
+ values being 16, 24 and 32.
+*/
+
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
+{
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+ if((blen & 3) || blen < 16 || blen > 32)
+ {
+ cx->n_blk = 0; return aes_bad;
+ }
+
+ cx->n_blk = blen;
+ return aes_good;
+}
+
+#endif
+
+/* Initialise the key schedule from the user supplied key. The key
+ length is now specified in bytes - 16, 24 or 32 as appropriate.
+ This corresponds to bit lengths of 128, 192 and 256 bits, and
+ to Nk values of 4, 6 and 8 respectively.
+
+ The following macros implement a single cycle in the key
+ schedule generation process. The number of cycles needed
+ for each cx->n_blk and nk value is:
+
+ nk = 4 5 6 7 8
+ ------------------------------
+ cx->n_blk = 4 10 9 8 7 7
+ cx->n_blk = 5 14 11 10 9 9
+ cx->n_blk = 6 19 15 12 11 11
+ cx->n_blk = 7 21 19 16 13 14
+ cx->n_blk = 8 29 23 19 17 14
+*/
+
+/* Initialise the key schedule from the user supplied key. The key
+ length is now specified in bytes - 16, 20, 24, 28 or 32 as
+ appropriate. This corresponds to bit lengths of 128, 160, 192,
+ 224 and 256 bits, and to Nk values of 4, 5, 6, 7 & 8 respectively.
+ */
+
+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
+#define cp(t,f) *t++ = *f++
+
+#if BLOCK_SIZE == 16
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
+#elif BLOCK_SIZE == 20
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
+ cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
+ mx(d,s)
+#elif BLOCK_SIZE == 24
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s)
+#elif BLOCK_SIZE == 28
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s); mx(d,s)
+#elif BLOCK_SIZE == 32
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
+#else
+
+#define cpy(d,s) \
+switch(nc) \
+{ case 8: cp(d,s); \
+ case 7: cp(d,s); \
+ case 6: cp(d,s); \
+ case 5: cp(d,s); \
+ case 4: cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s); \
+}
+
+#define mix(d,s) \
+switch(nc) \
+{ case 8: mx(d,s); \
+ case 7: mx(d,s); \
+ case 6: mx(d,s); \
+ case 5: mx(d,s); \
+ case 4: mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s); \
+}
+
+#endif
+
+/* The following macros implement a single cycle in the key
+ schedule generation process. The number of cycles needed
+ for each cx->n_blk and nk value is:
+
+ nk = 4 5 6 7 8
+ -----------------------
+ cx->n_blk = 4 10 9 8 7 7
+ cx->n_blk = 5 14 11 10 9 9
+ cx->n_blk = 6 19 15 12 11 11
+ cx->n_blk = 7 21 19 16 13 14
+ cx->n_blk = 8 29 23 19 17 14
+*/
+
+#define ks4(i) \
+{ p ^= ls_box(s,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
+ cx->k_sch[4*(i)+4] = p; \
+ cx->k_sch[4*(i)+5] = q; \
+ cx->k_sch[4*(i)+6] = r; \
+ cx->k_sch[4*(i)+7] = s; \
+}
+
+#define ks5(i) \
+{ p ^= ls_box(t,3) ^ rcon_tab[i]; q ^= p; \
+ r ^= q; s ^= r; t ^= s; \
+ cx->k_sch[5*(i)+ 5] = p; \
+ cx->k_sch[5*(i)+ 6] = q; \
+ cx->k_sch[5*(i)+ 7] = r; \
+ cx->k_sch[5*(i)+ 8] = s; \
+ cx->k_sch[5*(i)+ 9] = t; \
+}
+
+#define ks6(i) \
+{ p ^= ls_box(u,3) ^ rcon_tab[i]; q ^= p; \
+ r ^= q; s ^= r; t ^= s; u ^= t; \
+ cx->k_sch[6*(i)+ 6] = p; \
+ cx->k_sch[6*(i)+ 7] = q; \
+ cx->k_sch[6*(i)+ 8] = r; \
+ cx->k_sch[6*(i)+ 9] = s; \
+ cx->k_sch[6*(i)+10] = t; \
+ cx->k_sch[6*(i)+11] = u; \
+}
+
+#define ks7(i) \
+{ p ^= ls_box(v,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
+ t ^= ls_box(s,0); u ^= t; v ^= u; \
+ cx->k_sch[7*(i)+ 7] = p; \
+ cx->k_sch[7*(i)+ 8] = q; \
+ cx->k_sch[7*(i)+ 9] = r; \
+ cx->k_sch[7*(i)+10] = s; \
+ cx->k_sch[7*(i)+11] = t; \
+ cx->k_sch[7*(i)+12] = u; \
+ cx->k_sch[7*(i)+13] = v; \
+}
+
+#define ks8(i) \
+{ p ^= ls_box(w,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
+ t ^= ls_box(s,0); u ^= t; v ^= u; w ^= v; \
+ cx->k_sch[8*(i)+ 8] = p; \
+ cx->k_sch[8*(i)+ 9] = q; \
+ cx->k_sch[8*(i)+10] = r; \
+ cx->k_sch[8*(i)+11] = s; \
+ cx->k_sch[8*(i)+12] = t; \
+ cx->k_sch[8*(i)+13] = u; \
+ cx->k_sch[8*(i)+14] = v; \
+ cx->k_sch[8*(i)+15] = w; \
+}
+
+#if defined(ENCRYPTION_KEY_SCHEDULE)
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{ uint32_t i,p,q,r,s,t,u,v,w;
+
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+#if !defined(BLOCK_SIZE)
+ if(!cx->n_blk) cx->n_blk = 16;
+#else
+ cx->n_blk = BLOCK_SIZE;
+#endif
+
+ cx->n_blk = (cx->n_blk & ~3) | 1;
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+
+ cx->k_sch[0] = p = word_in(in_key );
+ cx->k_sch[1] = q = word_in(in_key + 4);
+ cx->k_sch[2] = r = word_in(in_key + 8);
+ cx->k_sch[3] = s = word_in(in_key + 12);
+
+#if BLOCK_SIZE == 16 && defined(UNROLL)
+
+ switch(klen >> 2)
+ {
+ case 4: ks4(0); ks4(1); ks4(2); ks4(3);
+ ks4(4); ks4(5); ks4(6); ks4(7);
+ ks4(8); ks4(9);
+ cx->n_rnd = 10; break;
+ case 5: cx->k_sch[4] = t = word_in(in_key + 16);
+ ks5(0); ks5(1); ks5(2); ks5(3);
+ ks5(4); ks5(5); ks5(6); ks5(7);
+ ks5(8);
+ cx->n_rnd = 11; break;
+ case 6: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ ks6(0); ks6(1); ks6(2); ks6(3);
+ ks6(4); ks6(5); ks6(6); ks6(7);
+ cx->n_rnd = 12; break;
+ case 7: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ cx->k_sch[6] = v = word_in(in_key + 24);
+ ks7(0); ks7(1); ks7(2); ks7(3);
+ ks7(4); ks7(5); ks7(6);
+ cx->n_rnd = 13; break;
+ case 8: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ cx->k_sch[6] = v = word_in(in_key + 24);
+ cx->k_sch[7] = w = word_in(in_key + 28);
+ ks8(0); ks8(1); ks8(2); ks8(3);
+ ks8(4); ks8(5); ks8(6);
+ cx->n_rnd = 14; break;
+ default:cx->n_rnd = 0; return aes_bad;
+ }
+#else
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+ {
+ uint32_t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
+ switch(klen >> 2)
+ {
+ case 4: for(i = 0; i < l; ++i)
+ ks4(i);
+ break;
+ case 5: cx->k_sch[4] = t = word_in(in_key + 16);
+ for(i = 0; i < l; ++i)
+ ks5(i);
+ break;
+ case 6: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ for(i = 0; i < l; ++i)
+ ks6(i);
+ break;
+ case 7: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ cx->k_sch[6] = v = word_in(in_key + 24);
+ for(i = 0; i < l; ++i)
+ ks7(i);
+ break;
+ case 8: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ cx->k_sch[6] = v = word_in(in_key + 24);
+ cx->k_sch[7] = w = word_in(in_key + 28);
+ for(i = 0; i < l; ++i)
+ ks8(i);
+ break;
+ }
+ }
+#endif
+
+ return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION_KEY_SCHEDULE)
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{ uint32_t i,p,q,r,s,t,u,v,w;
+ dec_imvars
+
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+#if !defined(BLOCK_SIZE)
+ if(!cx->n_blk) cx->n_blk = 16;
+#else
+ cx->n_blk = BLOCK_SIZE;
+#endif
+
+ cx->n_blk = (cx->n_blk & ~3) | 2;
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+
+ cx->k_sch[0] = p = word_in(in_key );
+ cx->k_sch[1] = q = word_in(in_key + 4);
+ cx->k_sch[2] = r = word_in(in_key + 8);
+ cx->k_sch[3] = s = word_in(in_key + 12);
+
+#if BLOCK_SIZE == 16 && defined(UNROLL)
+
+ switch(klen >> 2)
+ {
+ case 4: ks4(0); ks4(1); ks4(2); ks4(3);
+ ks4(4); ks4(5); ks4(6); ks4(7);
+ ks4(8); ks4(9);
+ cx->n_rnd = 10; break;
+ case 5: cx->k_sch[4] = t = word_in(in_key + 16);
+ ks5(0); ks5(1); ks5(2); ks5(3);
+ ks5(4); ks5(5); ks5(6); ks5(7);
+ ks5(8);
+ cx->n_rnd = 11; break;
+ case 6: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ ks6(0); ks6(1); ks6(2); ks6(3);
+ ks6(4); ks6(5); ks6(6); ks6(7);
+ cx->n_rnd = 12; break;
+ case 7: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ cx->k_sch[6] = v = word_in(in_key + 24);
+ ks7(0); ks7(1); ks7(2); ks7(3);
+ ks7(4); ks7(5); ks7(6);
+ cx->n_rnd = 13; break;
+ case 8: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ cx->k_sch[6] = v = word_in(in_key + 24);
+ cx->k_sch[7] = w = word_in(in_key + 28);
+ ks8(0); ks8(1); ks8(2); ks8(3);
+ ks8(4); ks8(5); ks8(6);
+ cx->n_rnd = 14; break;
+ default:cx->n_rnd = 0; return aes_bad;
+ }
+#else
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+ {
+ uint32_t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
+ switch(klen >> 2)
+ {
+ case 4: for(i = 0; i < l; ++i)
+ ks4(i);
+ break;
+ case 5: cx->k_sch[4] = t = word_in(in_key + 16);
+ for(i = 0; i < l; ++i)
+ ks5(i);
+ break;
+ case 6: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ for(i = 0; i < l; ++i)
+ ks6(i);
+ break;
+ case 7: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ cx->k_sch[6] = v = word_in(in_key + 24);
+ for(i = 0; i < l; ++i)
+ ks7(i);
+ break;
+ case 8: cx->k_sch[4] = t = word_in(in_key + 16);
+ cx->k_sch[5] = u = word_in(in_key + 20);
+ cx->k_sch[6] = v = word_in(in_key + 24);
+ cx->k_sch[7] = w = word_in(in_key + 28);
+ for(i = 0; i < l; ++i)
+ ks8(i);
+ break;
+ }
+ }
+#endif
+
+#if (DEC_ROUND != NO_TABLES)
+ for(i = nc; i < nc * cx->n_rnd; ++i)
+ cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
+#endif
+
+ return aes_good;
+}
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/aesopt.h b/src/lib/crypto/builtin/aes/aesopt.h
new file mode 100644
index 000000000000..6588b7fc8686
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aesopt.h
@@ -0,0 +1,852 @@
+/*
+ * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ * built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explcit or implied warranties
+ * in respect of any properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ */
+
+/*
+ Issue Date: 07/02/2002
+
+ This file contains the compilation options for AES (Rijndael) and code
+ that is common across encryption, key scheduling and table generation.
+
+
+ OPERATION
+
+ These source code files implement the AES algorithm Rijndael designed by
+ Joan Daemen and Vincent Rijmen. The version in aes.c is designed for
+ block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while
+ that in aespp.c provides for block and keys sizes of 128, 160, 192, 224
+ and 256 bits (16, 20, 24, 28 and 32 bytes). This file is a common header
+ file for these two implementations and for aesref.c, which is a reference
+ implementation.
+
+ This version is designed for flexibility and speed using operations on
+ 32-bit words rather than operations on bytes. It provides aes_both fixed
+ and dynamic block and key lengths and can also run with either big or
+ little endian internal byte order (see aes.h). It inputs block and key
+ lengths in bytes with the legal values being 16, 24 and 32 for aes.c and
+ 16, 20, 24, 28 and 32 for aespp.c
+
+ THE CIPHER INTERFACE
+
+ uint8_t (an unsigned 8-bit type)
+ uint32_t (an unsigned 32-bit type)
+ aes_fret (a signed 16 bit type for function return values)
+ aes_good (value != 0, a good return)
+ aes_bad (value == 0, an error return)
+ struct aes_ctx (structure for the cipher encryption context)
+ struct aes_ctx (structure for the cipher decryption context)
+ aes_rval the function return type (aes_fret if not DLL)
+
+ C subroutine calls:
+
+ aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
+ aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+ aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+ aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
+ aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+ aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+ IMPORTANT NOTE: If you are using this C interface and your compiler does
+ not set the memory used for objects to zero before use, you will need to
+ ensure that cx.s_flg is set to zero before using these subroutine calls.
+
+ C++ aes class subroutines:
+
+ class AESclass for encryption
+ class AESclass for decryption
+
+ aes_rval len(unsigned int blen = 16);
+ aes_rval key(const unsigned char in_key[], unsigned int klen);
+ aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+ aes_rval len(unsigned int blen = 16);
+ aes_rval key(const unsigned char in_key[], unsigned int klen);
+ aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+ The block length inputs to set_block and set_key are in numbers of
+ BYTES, not bits. The calls to subroutines must be made in the above
+ order but multiple calls can be made without repeating earlier calls
+ if their parameters have not changed. If the cipher block length is
+ variable but set_blk has not been called before cipher operations a
+ value of 16 is assumed (that is, the AES block size). In contrast to
+ earlier versions the block and key length parameters are now checked
+ for correctness and the encryption and decryption routines check to
+ ensure that an appropriate key has been set before they are called.
+
+ COMPILATION
+
+ The files used to provide AES (Rijndael) are
+
+ a. aes.h for the definitions needed for use in C.
+ b. aescpp.h for the definitions needed for use in C++.
+ c. aesopt.h for setting compilation options (also includes common
+ code).
+ d. aescrypt.c for encryption and decrytpion, or
+ e. aescrypt.asm for encryption and decryption using assembler code.
+ f. aeskey.c for key scheduling.
+ g. aestab.c for table loading or generation.
+ h. uitypes.h for defining fixed length unsigned integers.
+
+ The assembler code uses the NASM assembler. The above files provice
+ block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
+ If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
+ aeskey.c respectively, the block and key lengths can then be 16, 20,
+ 24, 28 or 32 bytes. However this code has not been optimised to the
+ same extent and is hence slower (esepcially for the AES block size
+ of 16 bytes).
+
+ To compile AES (Rijndael) for use in C code use aes.h and exclude
+ the AES_DLL define in aes.h
+
+ To compile AES (Rijndael) for use in in C++ code use aescpp.h and
+ exclude the AES_DLL define in aes.h
+
+ To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
+ aes.h, include the AES_DLL define and compile the DLL. If using
+ the test files to test the DLL, exclude aes.c from the test build
+ project and compile it with the same defines as used for the DLL
+ (ensure that the DLL path is correct)
+
+ CONFIGURATION OPTIONS (here and in aes.h)
+
+ a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24
+ or 32 for the standard code, or 16, 20, 24, 28 or 32 for the
+ extended code) or leave this undefined for dynamically variable
+ block size (this will result in much slower code).
+ b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
+ c. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
+ d. If you want the code to run in a specific internal byte order, then
+ INTERNAL_BYTE_ORDER must be set accordingly.
+ e. set other configuration options decribed below.
+*/
+
+#ifndef _AESOPT_H
+#define _AESOPT_H
+
+/* START OF CONFIGURATION OPTIONS
+
+ USE OF DEFINES
+
+ Later in this section there are a number of defines that control
+ the operation of the code. In each section, the purpose of each
+ define is explained so that the relevant form can be included or
+ excluded by setting either 1's or 0's respectively on the branches
+ of the related #if clauses.
+*/
+
+#include "autoconf.h"
+
+/* 1. PLATFORM SPECIFIC INCLUDES */
+
+#if /* defined(__GNUC__) || */ defined(__GNU_LIBRARY__)
+# include <endian.h>
+# include <byteswap.h>
+#elif defined(__CRYPTLIB__)
+# if defined( INC_ALL )
+# include "crypt.h"
+# elif defined( INC_CHILD )
+# include "../crypt.h"
+# else
+# include "crypt.h"
+# endif
+# if defined(DATA_LITTLEENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# else
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif defined(_MSC_VER)
+# include <stdlib.h>
+#elif defined(__m68k__) && defined(__palmos__)
+# include <FloatMgr.h> /* defines BIG_ENDIAN */
+#elif defined(_MIPSEB)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#elif defined(_MIPSEL)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif defined(_WIN32)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif !defined(_WIN32)
+# include <stdlib.h>
+# if defined(HAVE_ENDIAN_H)
+# include <endian.h>
+# elif defined(HAVE_MACHINE_ENDIAN_H)
+# include <machine/endian.h>
+# else
+# include <sys/param.h>
+# endif
+#endif
+
+/* 2. BYTE ORDER IN 32-BIT WORDS
+
+ To obtain the highest speed on processors with 32-bit words, this code
+ needs to determine the order in which bytes are packed into such words.
+ The following block of code is an attempt to capture the most obvious
+ ways in which various environemnts specify heir endian definitions. It
+ may well fail, in which case the definitions will need to be set by
+ editing at the points marked **** EDIT HERE IF NECESSARY **** below.
+*/
+#define AES_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
+#define AES_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+# if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+# if defined(BYTE_ORDER)
+# if (BYTE_ORDER == LITTLE_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif (BYTE_ORDER == BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+# endif
+# elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+# if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+# if defined(_BYTE_ORDER)
+# if (_BYTE_ORDER == _LITTLE_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif (_BYTE_ORDER == _BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+# endif
+# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif 0 /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif 0 /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#elif 1
+#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#define UNKNOWN_BYTE_ORDER /* we're guessing */
+#endif
+#endif
+
+/* 3. ASSEMBLER SUPPORT
+
+ If the assembler code is used for encryption and decryption this file only
+ provides key scheduling so the following defines are used
+*/
+#ifdef AES_ASM
+#define ENCRYPTION_KEY_SCHEDULE
+#define DECRYPTION_KEY_SCHEDULE
+#endif
+
+/* 4. FUNCTIONS REQUIRED
+
+ This implementation provides five main subroutines which provide for
+ setting block length, setting encryption and decryption keys and for
+ encryption and decryption. When the assembler code is not being used
+ the following definition blocks allow the selection of the routines
+ that are to be included in the compilation.
+*/
+#if 1
+#ifndef AES_ASM
+#define SET_BLOCK_LENGTH
+#endif
+#endif
+
+#if 1
+#ifndef AES_ASM
+#define ENCRYPTION_KEY_SCHEDULE
+#endif
+#endif
+
+#if 1
+#ifndef AES_ASM
+#define DECRYPTION_KEY_SCHEDULE
+#endif
+#endif
+
+#if 1
+#ifndef AES_ASM
+#define ENCRYPTION
+#endif
+#endif
+
+#if 1
+#ifndef AES_ASM
+#define DECRYPTION
+#endif
+#endif
+
+/* 5. BYTE ORDER WITHIN 32 BIT WORDS
+
+ The fundamental data processing units in Rijndael are 8-bit bytes. The
+ input, output and key input are all enumerated arrays of bytes in which
+ bytes are numbered starting at zero and increasing to one less than the
+ number of bytes in the array in question. This enumeration is only used
+ for naming bytes and does not imply any adjacency or order relationship
+ from one byte to another. When these inputs and outputs are considered
+ as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
+ byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
+ In this implementation bits are numbered from 0 to 7 starting at the
+ numerically least significant end of each byte (bit n represents 2^n).
+
+ However, Rijndael can be implemented more efficiently using 32-bit
+ words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
+ into word[n]. While in principle these bytes can be assembled into words
+ in any positions, this implementation only supports the two formats in
+ which bytes in adjacent positions within words also have adjacent byte
+ numbers. This order is called big-endian if the lowest numbered bytes
+ in words have the highest numeric significance and little-endian if the
+ opposite applies.
+
+ This code can work in either order irrespective of the order used by the
+ machine on which it runs. Normally the internal byte order will be set
+ to the order of the processor on which the code is to be run but this
+ define can be used to reverse this in special situations
+*/
+#if 1
+#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
+#elif defined(AES_LITTLE_ENDIAN)
+#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif defined(AES_BIG_ENDIAN)
+#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
+#endif
+
+/* 6. FAST INPUT/OUTPUT OPERATIONS.
+
+ On some machines it is possible to improve speed by transferring the
+ bytes in the input and output arrays to and from the internal 32-bit
+ variables by addressing these arrays as if they are arrays of 32-bit
+ words. On some machines this will always be possible but there may
+ be a large performance penalty if the byte arrays are not aligned on
+ the normal word boundaries. On other machines this technique will
+ lead to memory access errors when such 32-bit word accesses are not
+ properly aligned. The option SAFE_IO avoids such problems but will
+ often be slower on those machines that support misaligned access
+ (especially so if care is taken to align the input and output byte
+ arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
+ assumed that access to byte arrays as if they are arrays of 32-bit
+ words will not cause problems when such accesses are misaligned.
+*/
+#if 1
+#define SAFE_IO
+#endif
+
+/*
+ * If PLATFORM_BYTE_ORDER does not match the actual machine byte
+ * order, the fast word-access code will cause incorrect results.
+ * Therefore, SAFE_IO is required when the byte order is unknown.
+ */
+#if !defined(SAFE_IO) && defined(UNKNOWN_BYTE_ORDER)
+# error "SAFE_IO must be defined if machine byte order is unknown."
+#endif
+
+/* 7. LOOP UNROLLING
+
+ The code for encryption and decrytpion cycles through a number of rounds
+ that can be implemented either in a loop or by expanding the code into a
+ long sequence of instructions, the latter producing a larger program but
+ one that will often be much faster. The latter is called loop unrolling.
+ There are also potential speed advantages in expanding two iterations in
+ a loop with half the number of iterations, which is called partial loop
+ unrolling. The following options allow partial or full loop unrolling
+ to be set independently for encryption and decryption
+*/
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)
+#define ENC_UNROLL FULL
+#elif 0
+#define ENC_UNROLL PARTIAL
+#else
+#define ENC_UNROLL NONE
+#endif
+
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)
+#define DEC_UNROLL FULL
+#elif 0
+#define DEC_UNROLL PARTIAL
+#else
+#define DEC_UNROLL NONE
+#endif
+
+/* 8. FIXED OR DYNAMIC TABLES
+
+ When this section is included the tables used by the code are compiled
+ statically into the binary file. Otherwise they are computed once when
+ the code is first used.
+*/
+#if 1
+#define FIXED_TABLES
+#endif
+
+/* 9. FAST FINITE FIELD OPERATIONS
+
+ If this section is included, tables are used to provide faster finite
+ field arithmetic (this has no effect if FIXED_TABLES is defined).
+*/
+#if 1
+#define FF_TABLES
+#endif
+
+/* 10. INTERNAL STATE VARIABLE FORMAT
+
+ The internal state of Rijndael is stored in a number of local 32-bit
+ word varaibles which can be defined either as an array or as individual
+ names variables. Include this section if you want to store these local
+ varaibles in arrays. Otherwise individual local variables will be used.
+*/
+#if 1
+#define ARRAYS
+#endif
+
+/* In this implementation the columns of the state array are each held in
+ 32-bit words. The state array can be held in various ways: in an array
+ of words, in a number of individual word variables or in a number of
+ processor registers. The following define maps a variable name x and
+ a column number c to the way the state array variable is to be held.
+ The first define below maps the state into an array x[c] whereas the
+ second form maps the state into a number of individual variables x0,
+ x1, etc. Another form could map individual state colums to machine
+ register names.
+*/
+
+#if defined(ARRAYS)
+#define s(x,c) x[c]
+#else
+#define s(x,c) x##c
+#endif
+
+/* 11. VARIABLE BLOCK SIZE SPEED
+
+ This section is only relevant if you wish to use the variable block
+ length feature of the code. Include this section if you place more
+ emphasis on speed rather than code size.
+*/
+#if 1
+#define FAST_VARIABLE
+#endif
+
+/* 12. INTERNAL TABLE CONFIGURATION
+
+ This cipher proceeds by repeating in a number of cycles known as 'rounds'
+ which are implemented by a round function which can optionally be speeded
+ up using tables. The basic tables are each 256 32-bit words, with either
+ one or four tables being required for each round function depending on
+ how much speed is required. The encryption and decryption round functions
+ are different and the last encryption and decrytpion round functions are
+ different again making four different round functions in all.
+
+ This means that:
+ 1. Normal encryption and decryption rounds can each use either 0, 1
+ or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+ 2. The last encryption and decryption rounds can also use either 0, 1
+ or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+
+ Include or exclude the appropriate definitions below to set the number
+ of tables used by this implementation.
+*/
+
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) /* set tables for the normal encryption round */
+#define ENC_ROUND FOUR_TABLES
+#elif 0
+#define ENC_ROUND ONE_TABLE
+#else
+#define ENC_ROUND NO_TABLES
+#endif
+
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) /* set tables for the last encryption round */
+#define LAST_ENC_ROUND FOUR_TABLES
+#elif 0
+#define LAST_ENC_ROUND ONE_TABLE
+#else
+#define LAST_ENC_ROUND NO_TABLES
+#endif
+
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) /* set tables for the normal decryption round */
+#define DEC_ROUND FOUR_TABLES
+#elif 0
+#define DEC_ROUND ONE_TABLE
+#else
+#define DEC_ROUND NO_TABLES
+#endif
+
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) /* set tables for the last decryption round */
+#define LAST_DEC_ROUND FOUR_TABLES
+#elif 0
+#define LAST_DEC_ROUND ONE_TABLE
+#else
+#define LAST_DEC_ROUND NO_TABLES
+#endif
+
+/* The decryption key schedule can be speeded up with tables in the same
+ way that the round functions can. Include or exclude the following
+ defines to set this requirement.
+*/
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)
+#define KEY_SCHED FOUR_TABLES
+#elif 0
+#define KEY_SCHED ONE_TABLE
+#else
+#define KEY_SCHED NO_TABLES
+#endif
+
+/* END OF CONFIGURATION OPTIONS */
+
+#define NO_TABLES 0 /* DO NOT CHANGE */
+#define ONE_TABLE 1 /* DO NOT CHANGE */
+#define FOUR_TABLES 4 /* DO NOT CHANGE */
+#define NONE 0 /* DO NOT CHANGE */
+#define PARTIAL 1 /* DO NOT CHANGE */
+#define FULL 2 /* DO NOT CHANGE */
+
+#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32)
+#error An illegal block size has been specified.
+#endif
+
+#if !defined(BLOCK_SIZE)
+#define RC_LENGTH 29
+#else
+#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11)
+#endif
+
+/* Disable at least some poor combinations of options */
+
+#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
+#undef LAST_ENC_ROUND
+#define LAST_ENC_ROUND NO_TABLES
+#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
+#undef LAST_ENC_ROUND
+#define LAST_ENC_ROUND ONE_TABLE
+#endif
+
+#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
+#undef ENC_UNROLL
+#define ENC_UNROLL NONE
+#endif
+
+#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
+#undef LAST_DEC_ROUND
+#define LAST_DEC_ROUND NO_TABLES
+#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
+#undef LAST_DEC_ROUND
+#define LAST_DEC_ROUND ONE_TABLE
+#endif
+
+#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
+#undef DEC_UNROLL
+#define DEC_UNROLL NONE
+#endif
+
+#include "aes.h"
+
+ /*
+ upr(x,n): rotates bytes within words by n positions, moving bytes to
+ higher index positions with wrap around into low positions
+ ups(x,n): moves bytes by n positions to higher index positions in
+ words but without wrap around
+ bval(x,n): extracts a byte from a word
+ */
+
+#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
+#if defined(_MSC_VER)
+#define upr(x,n) _lrotl((x), 8 * (n))
+#else
+#define upr(x,n) (((x) << (8 * (n))) | ((x) >> (32 - 8 * (n))))
+#endif
+#define ups(x,n) ((x) << (8 * (n)))
+#define bval(x,n) ((uint8_t)((x) >> (8 * (n))))
+#define bytes2word(b0, b1, b2, b3) \
+ (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
+#endif
+
+#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
+#define upr(x,n) (((x) >> (8 * (n))) | ((x) << (32 - 8 * (n))))
+#define ups(x,n) ((x) >> (8 * (n))))
+#define bval(x,n) ((uint8_t)((x) >> (24 - 8 * (n))))
+#define bytes2word(b0, b1, b2, b3) \
+ (((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3))
+#endif
+
+#if defined(SAFE_IO)
+
+#define word_in(x) bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
+#define word_out(x,v) { (x)[0] = bval(v,0); (x)[1] = bval(v,1); \
+ (x)[2] = bval(v,2); (x)[3] = bval(v,3); }
+
+#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
+
+#define word_in(x) *(uint32_t*)(x)
+#define word_out(x,v) *(uint32_t*)(x) = (v)
+
+#else
+
+#if !defined(bswap_32)
+#if !defined(_MSC_VER)
+#define _lrotl(x,n) (((x) << n) | ((x) >> (32 - n)))
+#endif
+#define bswap_32(x) ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 0xff00ff00))
+#endif
+
+#define word_in(x) bswap_32(*(uint32_t*)(x))
+#define word_out(x,v) *(uint32_t*)(x) = bswap_32(v)
+
+#endif
+
+/* the finite field modular polynomial and elements */
+
+#define WPOLY 0x011b
+#define BPOLY 0x1b
+
+/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
+
+#define m1 0x80808080
+#define m2 0x7f7f7f7f
+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
+
+/* The following defines provide alternative definitions of FFmulX that might
+ give improved performance if a fast 32-bit multiply is not available. Note
+ that a temporary variable u needs to be defined where FFmulX is used.
+
+#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
+#define m4 (0x01010101 * BPOLY)
+#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
+*/
+
+/* Work out which tables are needed for the different options */
+
+#ifdef AES_ASM
+#ifdef ENC_ROUND
+#undef ENC_ROUND
+#endif
+#define ENC_ROUND FOUR_TABLES
+#ifdef LAST_ENC_ROUND
+#undef LAST_ENC_ROUND
+#endif
+#define LAST_ENC_ROUND FOUR_TABLES
+#ifdef DEC_ROUND
+#undef DEC_ROUND
+#endif
+#define DEC_ROUND FOUR_TABLES
+#ifdef LAST_DEC_ROUND
+#undef LAST_DEC_ROUND
+#endif
+#define LAST_DEC_ROUND FOUR_TABLES
+#ifdef KEY_SCHED
+#undef KEY_SCHED
+#define KEY_SCHED FOUR_TABLES
+#endif
+#endif
+
+#if defined(ENCRYPTION) || defined(AES_ASM)
+#if ENC_ROUND == ONE_TABLE
+#define FT1_SET
+#elif ENC_ROUND == FOUR_TABLES
+#define FT4_SET
+#else
+#define SBX_SET
+#endif
+#if LAST_ENC_ROUND == ONE_TABLE
+#define FL1_SET
+#elif LAST_ENC_ROUND == FOUR_TABLES
+#define FL4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#if defined(DECRYPTION) || defined(AES_ASM)
+#if DEC_ROUND == ONE_TABLE
+#define IT1_SET
+#elif DEC_ROUND == FOUR_TABLES
+#define IT4_SET
+#else
+#define ISB_SET
+#endif
+#if LAST_DEC_ROUND == ONE_TABLE
+#define IL1_SET
+#elif LAST_DEC_ROUND == FOUR_TABLES
+#define IL4_SET
+#elif !defined(ISB_SET)
+#define ISB_SET
+#endif
+#endif
+
+#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
+#if KEY_SCHED == ONE_TABLE
+#define LS1_SET
+#define IM1_SET
+#elif KEY_SCHED == FOUR_TABLES
+#define LS4_SET
+#define IM4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#ifdef FIXED_TABLES
+#define prefx extern const
+#else
+#define prefx extern
+extern uint8_t tab_init;
+void gen_tabs(void);
+#endif
+
+prefx uint32_t rcon_tab[29];
+
+#ifdef SBX_SET
+prefx uint8_t s_box[256];
+#endif
+
+#ifdef ISB_SET
+prefx uint8_t inv_s_box[256];
+#endif
+
+#ifdef FT1_SET
+prefx uint32_t ft_tab[256];
+#endif
+
+#ifdef FT4_SET
+prefx uint32_t ft_tab[4][256];
+#endif
+
+#ifdef FL1_SET
+prefx uint32_t fl_tab[256];
+#endif
+
+#ifdef FL4_SET
+prefx uint32_t fl_tab[4][256];
+#endif
+
+#ifdef IT1_SET
+prefx uint32_t it_tab[256];
+#endif
+
+#ifdef IT4_SET
+prefx uint32_t it_tab[4][256];
+#endif
+
+#ifdef IL1_SET
+prefx uint32_t il_tab[256];
+#endif
+
+#ifdef IL4_SET
+prefx uint32_t il_tab[4][256];
+#endif
+
+#ifdef LS1_SET
+#ifdef FL1_SET
+#undef LS1_SET
+#else
+prefx uint32_t ls_tab[256];
+#endif
+#endif
+
+#ifdef LS4_SET
+#ifdef FL4_SET
+#undef LS4_SET
+#else
+prefx uint32_t ls_tab[4][256];
+#endif
+#endif
+
+#ifdef IM1_SET
+prefx uint32_t im_tab[256];
+#endif
+
+#ifdef IM4_SET
+prefx uint32_t im_tab[4][256];
+#endif
+
+/* Set the number of columns in nc. Note that it is important */
+/* that nc is a constant which is known at compile time if the */
+/* highest speed version of the code is needed */
+
+#if defined(BLOCK_SIZE)
+#define nc (BLOCK_SIZE >> 2)
+#else
+#define nc (cx->n_blk >> 2)
+#endif
+
+/* generic definitions of Rijndael macros that use of tables */
+
+#define no_table(x,box,vf,rf,c) bytes2word( \
+ box[bval(vf(x,0,c),rf(0,c))], \
+ box[bval(vf(x,1,c),rf(1,c))], \
+ box[bval(vf(x,2,c),rf(2,c))], \
+ box[bval(vf(x,3,c),rf(3,c))])
+
+#define one_table(x,op,tab,vf,rf,c) \
+ ( tab[bval(vf(x,0,c),rf(0,c))] \
+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
+
+#define four_tables(x,tab,vf,rf,c) \
+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
+
+#define vf1(x,r,c) (x)
+#define rf1(r,c) (r)
+#define rf2(r,c) ((r-c)&3)
+
+/* perform forward and inverse column mix operation on four bytes in long word x in */
+/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
+
+#define dec_fmvars
+#if defined(FM4_SET) /* not currently used */
+#define fwd_mcol(x) four_tables(x,fm_tab,vf1,rf1,0)
+#elif defined(FM1_SET) /* not currently used */
+#define fwd_mcol(x) one_table(x,upr,fm_tab,vf1,rf1,0)
+#else
+#undef dec_fmvars
+#define dec_fmvars uint32_t f1, f2;
+#define fwd_mcol(x) (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1))
+#endif
+
+#define dec_imvars
+#if defined(IM4_SET)
+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
+#elif defined(IM1_SET)
+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
+#else
+#undef dec_imvars
+#define dec_imvars uint32_t f2, f4, f8, f9;
+#define inv_mcol(x) \
+ (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
+#endif
+
+#if defined(FL4_SET)
+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
+#elif defined(LS4_SET)
+#define ls_box(x,c) four_tables(x,ls_tab,vf1,rf2,c)
+#elif defined(FL1_SET)
+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
+#elif defined(LS1_SET)
+#define ls_box(x,c) one_table(x,upr,ls_tab,vf1,rf2,c)
+#else
+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
+#endif
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/aessrc.url b/src/lib/crypto/builtin/aes/aessrc.url
new file mode 100644
index 000000000000..0758737db3ca
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aessrc.url
@@ -0,0 +1 @@
+http://fp.gladman.plus.com/cryptography_technology/rijndael/index.htm
diff --git a/src/lib/crypto/builtin/aes/aestab.c b/src/lib/crypto/builtin/aes/aestab.c
new file mode 100644
index 000000000000..ef182d641c0d
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aestab.c
@@ -0,0 +1,493 @@
+/*
+ * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ * built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explcit or implied warranties
+ * in respect of any properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ */
+
+/* Issue Date: 07/02/2002 */
+
+#include "aesopt.h"
+
+#if defined(FIXED_TABLES) || !defined(FF_TABLES)
+
+/* finite field arithmetic operations */
+
+#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
+#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
+#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
+ ^ (((x>>5) & 4) * WPOLY))
+#define f3(x) (f2(x) ^ x)
+#define f9(x) (f8(x) ^ x)
+#define fb(x) (f8(x) ^ f2(x) ^ x)
+#define fd(x) (f8(x) ^ f4(x) ^ x)
+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
+
+#endif
+
+#if defined(FIXED_TABLES)
+
+#define sb_data(w) \
+ w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
+ w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
+ w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
+ w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
+ w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
+ w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
+ w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
+ w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
+ w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
+ w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
+ w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
+ w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
+ w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
+ w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
+ w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
+ w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
+ w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
+ w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
+ w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
+ w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
+ w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
+ w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
+ w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
+ w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
+ w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
+ w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
+ w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
+ w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
+ w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
+ w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
+ w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
+ w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
+
+#define isb_data(w) \
+ w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
+ w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
+ w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
+ w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
+ w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
+ w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
+ w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
+ w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
+ w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
+ w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
+ w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
+ w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
+ w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
+ w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
+ w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
+ w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
+ w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
+ w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
+ w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
+ w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
+ w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
+ w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
+ w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
+ w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
+ w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
+ w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
+ w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
+ w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
+ w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
+ w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
+ w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
+ w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
+
+#define mm_data(w) \
+ w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
+ w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
+ w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
+ w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
+ w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
+ w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
+ w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
+ w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
+ w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
+ w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
+ w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
+ w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
+ w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
+ w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
+ w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
+ w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
+ w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
+ w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
+ w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
+ w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
+ w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
+ w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
+ w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
+ w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
+ w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
+ w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
+ w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
+ w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
+ w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
+ w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
+ w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
+ w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
+
+#define h0(x) (x)
+
+/* These defines are used to ensure tables are generated in the
+ right format depending on the internal byte order required
+*/
+
+#define w0(p) bytes2word(p, 0, 0, 0)
+#define w1(p) bytes2word(0, p, 0, 0)
+#define w2(p) bytes2word(0, 0, p, 0)
+#define w3(p) bytes2word(0, 0, 0, p)
+
+/* Number of elements required in this table for different
+ block and key lengths is:
+
+ Rcon Table key length (bytes)
+ Length 16 20 24 28 32
+ ---------------------
+ block 16 | 10 9 8 7 7
+ length 20 | 14 11 10 9 9
+ (bytes) 24 | 19 15 12 11 11
+ 28 | 24 19 16 13 13
+ 32 | 29 23 19 17 14
+
+ this table can be a table of bytes if the key schedule
+ code is adjusted accordingly
+*/
+
+#define u0(p) bytes2word(f2(p), p, p, f3(p))
+#define u1(p) bytes2word(f3(p), f2(p), p, p)
+#define u2(p) bytes2word(p, f3(p), f2(p), p)
+#define u3(p) bytes2word(p, p, f3(p), f2(p))
+
+#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
+#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
+#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
+#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
+
+const uint32_t rcon_tab[29] =
+{
+ w0(0x01), w0(0x02), w0(0x04), w0(0x08),
+ w0(0x10), w0(0x20), w0(0x40), w0(0x80),
+ w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8),
+ w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f),
+ w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6),
+ w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
+ w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef),
+ w0(0xc5)
+};
+
+#ifdef SBX_SET
+const uint8_t s_box[256] = { sb_data(h0) };
+#endif
+#ifdef ISB_SET
+const uint8_t inv_s_box[256] = { isb_data(h0) };
+#endif
+
+#ifdef FT1_SET
+const uint32_t ft_tab[256] = { sb_data(u0) };
+#endif
+#ifdef FT4_SET
+const uint32_t ft_tab[4][256] =
+ { { sb_data(u0) }, { sb_data(u1) }, { sb_data(u2) }, { sb_data(u3) } };
+#endif
+
+#ifdef FL1_SET
+const uint32_t fl_tab[256] = { sb_data(w0) };
+#endif
+#ifdef FL4_SET
+const uint32_t fl_tab[4][256] =
+ { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
+#endif
+
+#ifdef IT1_SET
+const uint32_t it_tab[256] = { isb_data(v0) };
+#endif
+#ifdef IT4_SET
+const uint32_t it_tab[4][256] =
+ { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
+#endif
+
+#ifdef IL1_SET
+const uint32_t il_tab[256] = { isb_data(w0) };
+#endif
+#ifdef IL4_SET
+const uint32_t il_tab[4][256] =
+ { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
+#endif
+
+#ifdef LS1_SET
+const uint32_t ls_tab[256] = { sb_data(w0) };
+#endif
+#ifdef LS4_SET
+const uint32_t ls_tab[4][256] =
+ { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
+#endif
+
+#ifdef IM1_SET
+const uint32_t im_tab[256] = { mm_data(v0) };
+#endif
+#ifdef IM4_SET
+const uint32_t im_tab[4][256] =
+ { { mm_data(v0) }, { mm_data(v1) }, { mm_data(v2) }, { mm_data(v3) } };
+#endif
+
+#else /* dynamic table generation */
+
+uint8_t tab_init = 0;
+
+#define const
+
+uint32_t rcon_tab[RC_LENGTH];
+
+#ifdef SBX_SET
+uint8_t s_box[256];
+#endif
+#ifdef ISB_SET
+uint8_t inv_s_box[256];
+#endif
+
+#ifdef FT1_SET
+uint32_t ft_tab[256];
+#endif
+#ifdef FT4_SET
+uint32_t ft_tab[4][256];
+#endif
+
+#ifdef FL1_SET
+uint32_t fl_tab[256];
+#endif
+#ifdef FL4_SET
+uint32_t fl_tab[4][256];
+#endif
+
+#ifdef IT1_SET
+uint32_t it_tab[256];
+#endif
+#ifdef IT4_SET
+uint32_t it_tab[4][256];
+#endif
+
+#ifdef IL1_SET
+uint32_t il_tab[256];
+#endif
+#ifdef IL4_SET
+uint32_t il_tab[4][256];
+#endif
+
+#ifdef LS1_SET
+uint32_t ls_tab[256];
+#endif
+#ifdef LS4_SET
+uint32_t ls_tab[4][256];
+#endif
+
+#ifdef IM1_SET
+uint32_t im_tab[256];
+#endif
+#ifdef IM4_SET
+uint32_t im_tab[4][256];
+#endif
+
+#if !defined(FF_TABLES)
+
+/* Generate the tables for the dynamic table option
+
+ It will generally be sensible to use tables to compute finite
+ field multiplies and inverses but where memory is scarse this
+ code might sometimes be better. But it only has effect during
+ initialisation so its pretty unimportant in overall terms.
+*/
+
+/* return 2 ^ (n - 1) where n is the bit number of the highest bit
+ set in x with x in the range 1 < x < 0x00000200. This form is
+ used so that locals within fi can be bytes rather than words
+*/
+
+static uint8_t hibit(const uint32_t x)
+{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2));
+
+ r |= (r >> 2);
+ r |= (r >> 4);
+ return (r + 1) >> 1;
+}
+
+/* return the inverse of the finite field element x */
+
+static uint8_t fi(const uint8_t x)
+{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
+
+ if(x < 2) return x;
+
+ for(;;)
+ {
+ if(!n1) return v1;
+
+ while(n2 >= n1)
+ {
+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
+ }
+
+ if(!n2) return v2;
+
+ while(n1 >= n2)
+ {
+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
+ }
+ }
+}
+
+#else
+
+/* define the finite field multiplies required for Rijndael */
+
+#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
+#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
+#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
+#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
+#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
+#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
+#define fi(x) ((x) ? pow[255 - log[x]]: 0)
+
+#endif
+
+/* The forward and inverse affine transformations used in the S-box */
+
+#define fwd_affine(x) \
+ (w = (uint32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(uint8_t)(w^(w>>8)))
+
+#define inv_affine(x) \
+ (w = (uint32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(uint8_t)(w^(w>>8)))
+
+void gen_tabs(void)
+{ uint32_t i, w;
+
+#if defined(FF_TABLES)
+
+ uint8_t pow[512], log[256];
+
+ /* log and power tables for GF(2^8) finite field with
+ WPOLY as modular polynomial - the simplest primitive
+ root is 0x03, used here to generate the tables
+ */
+
+ i = 0; w = 1;
+ do
+ {
+ pow[i] = (uint8_t)w;
+ pow[i + 255] = (uint8_t)w;
+ log[w] = (uint8_t)i++;
+ w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
+ }
+ while (w != 1);
+
+#endif
+
+ for(i = 0, w = 1; i < RC_LENGTH; ++i)
+ {
+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
+ w = f2(w);
+ }
+
+ for(i = 0; i < 256; ++i)
+ { uint8_t b;
+
+ b = fwd_affine(fi((uint8_t)i));
+ w = bytes2word(f2(b), b, b, f3(b));
+
+#ifdef SBX_SET
+ s_box[i] = b;
+#endif
+
+#ifdef FT1_SET /* tables for a normal encryption round */
+ ft_tab[i] = w;
+#endif
+#ifdef FT4_SET
+ ft_tab[0][i] = w;
+ ft_tab[1][i] = upr(w,1);
+ ft_tab[2][i] = upr(w,2);
+ ft_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(b, 0, 0, 0);
+
+#ifdef FL1_SET /* tables for last encryption round (may also */
+ fl_tab[i] = w; /* be used in the key schedule) */
+#endif
+#ifdef FL4_SET
+ fl_tab[0][i] = w;
+ fl_tab[1][i] = upr(w,1);
+ fl_tab[2][i] = upr(w,2);
+ fl_tab[3][i] = upr(w,3);
+#endif
+
+#ifdef LS1_SET /* table for key schedule if fl_tab above is */
+ ls_tab[i] = w; /* not of the required form */
+#endif
+#ifdef LS4_SET
+ ls_tab[0][i] = w;
+ ls_tab[1][i] = upr(w,1);
+ ls_tab[2][i] = upr(w,2);
+ ls_tab[3][i] = upr(w,3);
+#endif
+
+ b = fi(inv_affine((uint8_t)i));
+ w = bytes2word(fe(b), f9(b), fd(b), fb(b));
+
+#ifdef IM1_SET /* tables for the inverse mix column operation */
+ im_tab[b] = w;
+#endif
+#ifdef IM4_SET
+ im_tab[0][b] = w;
+ im_tab[1][b] = upr(w,1);
+ im_tab[2][b] = upr(w,2);
+ im_tab[3][b] = upr(w,3);
+#endif
+
+#ifdef ISB_SET
+ inv_s_box[i] = b;
+#endif
+#ifdef IT1_SET /* tables for a normal decryption round */
+ it_tab[i] = w;
+#endif
+#ifdef IT4_SET
+ it_tab[0][i] = w;
+ it_tab[1][i] = upr(w,1);
+ it_tab[2][i] = upr(w,2);
+ it_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(b, 0, 0, 0);
+#ifdef IL1_SET /* tables for last decryption round */
+ il_tab[i] = w;
+#endif
+#ifdef IL4_SET
+ il_tab[0][i] = w;
+ il_tab[1][i] = upr(w,1);
+ il_tab[2][i] = upr(w,2);
+ il_tab[3][i] = upr(w,3);
+#endif
+ }
+
+ tab_init = 1;
+}
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/deps b/src/lib/crypto/builtin/aes/deps
new file mode 100644
index 000000000000..fcd5520cd7d3
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/deps
@@ -0,0 +1,9 @@
+#
+# Generated makefile dependencies follow.
+#
+aescrypt.so aescrypt.po $(OUTPRE)aescrypt.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h aes.h aescrypt.c aesopt.h
+aestab.so aestab.po $(OUTPRE)aestab.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ aes.h aesopt.h aestab.c
+aeskey.so aeskey.po $(OUTPRE)aeskey.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ aes.h aeskey.c aesopt.h
diff --git a/src/lib/crypto/builtin/aes/iaesx64.s b/src/lib/crypto/builtin/aes/iaesx64.s
new file mode 100644
index 000000000000..bc7210ab3039
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/iaesx64.s
@@ -0,0 +1,799 @@
+[bits 64]
+[CPU intelnop]
+
+; Copyright (c) 2010, Intel Corporation
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are met:
+;
+; * Redistributions of source code must retain the above copyright notice,
+; this list of conditions and the following disclaimer.
+; * Redistributions in binary form must reproduce the above copyright notice,
+; this list of conditions and the following disclaimer in the documentation
+; and/or other materials provided with the distribution.
+; * Neither the name of Intel Corporation nor the names of its contributors
+; may be used to endorse or promote products derived from this software
+; without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+; IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+%define iEncExpandKey128 k5_iEncExpandKey128
+%define iEncExpandKey256 k5_iEncExpandKey256
+%define iDecExpandKey128 k5_iDecExpandKey128
+%define iDecExpandKey256 k5_iDecExpandKey256
+%define iEnc128_CBC k5_iEnc128_CBC
+%define iEnc256_CBC k5_iEnc256_CBC
+%define iDec128_CBC k5_iDec128_CBC
+%define iDec256_CBC k5_iDec256_CBC
+
+%macro linux_setup 0
+%ifdef __linux__
+ mov rcx, rdi
+ mov rdx, rsi
+%endif
+%endmacro
+
+%macro inversekey 1
+ movdqu xmm1,%1
+ aesimc xmm0,xmm1
+ movdqu %1,xmm0
+%endmacro
+
+%macro aesdeclast1 1
+ aesdeclast xmm0,%1
+%endmacro
+
+%macro aesenclast1 1
+ aesenclast xmm0,%1
+%endmacro
+
+%macro aesdec1 1
+ aesdec xmm0,%1
+%endmacro
+
+%macro aesenc1 1
+ aesenc xmm0,%1
+%endmacro
+
+
+%macro aesdeclast1_u 1
+ movdqu xmm4,%1
+ aesdeclast xmm0,xmm4
+%endmacro
+
+%macro aesenclast1_u 1
+ movdqu xmm4,%1
+ aesenclast xmm0,xmm4
+%endmacro
+
+%macro aesdec1_u 1
+ movdqu xmm4,%1
+ aesdec xmm0,xmm4
+%endmacro
+
+%macro aesenc1_u 1
+ movdqu xmm4,%1
+ aesenc xmm0,xmm4
+%endmacro
+
+%macro aesdec4 1
+ movdqa xmm4,%1
+
+ aesdec xmm0,xmm4
+ aesdec xmm1,xmm4
+ aesdec xmm2,xmm4
+ aesdec xmm3,xmm4
+
+%endmacro
+
+%macro aesdeclast4 1
+ movdqa xmm4,%1
+
+ aesdeclast xmm0,xmm4
+ aesdeclast xmm1,xmm4
+ aesdeclast xmm2,xmm4
+ aesdeclast xmm3,xmm4
+
+%endmacro
+
+
+%macro aesenc4 1
+ movdqa xmm4,%1
+
+ aesenc xmm0,xmm4
+ aesenc xmm1,xmm4
+ aesenc xmm2,xmm4
+ aesenc xmm3,xmm4
+
+%endmacro
+
+%macro aesenclast4 1
+ movdqa xmm4,%1
+
+ aesenclast xmm0,xmm4
+ aesenclast xmm1,xmm4
+ aesenclast xmm2,xmm4
+ aesenclast xmm3,xmm4
+
+%endmacro
+
+
+%macro xor_with_input4 1
+ movdqu xmm4,[%1]
+ pxor xmm0,xmm4
+ movdqu xmm4,[%1+16]
+ pxor xmm1,xmm4
+ movdqu xmm4,[%1+32]
+ pxor xmm2,xmm4
+ movdqu xmm4,[%1+48]
+ pxor xmm3,xmm4
+%endmacro
+
+
+
+%macro load_and_xor4 2
+ movdqa xmm4,%2
+ movdqu xmm0,[%1 + 0*16]
+ pxor xmm0,xmm4
+ movdqu xmm1,[%1 + 1*16]
+ pxor xmm1,xmm4
+ movdqu xmm2,[%1 + 2*16]
+ pxor xmm2,xmm4
+ movdqu xmm3,[%1 + 3*16]
+ pxor xmm3,xmm4
+%endmacro
+
+%macro store4 1
+ movdqu [%1 + 0*16],xmm0
+ movdqu [%1 + 1*16],xmm1
+ movdqu [%1 + 2*16],xmm2
+ movdqu [%1 + 3*16],xmm3
+%endmacro
+
+%macro copy_round_keys 3
+ movdqu xmm4,[%2 + ((%3)*16)]
+ movdqa [%1 + ((%3)*16)],xmm4
+%endmacro
+
+
+%macro key_expansion_1_192 1
+ ;; Assumes the xmm3 includes all zeros at this point.
+ pshufd xmm2, xmm2, 11111111b
+ shufps xmm3, xmm1, 00010000b
+ pxor xmm1, xmm3
+ shufps xmm3, xmm1, 10001100b
+ pxor xmm1, xmm3
+ pxor xmm1, xmm2
+ movdqu [rdx+%1], xmm1
+%endmacro
+
+; Calculate w10 and w11 using calculated w9 and known w4-w5
+%macro key_expansion_2_192 1
+ movdqa xmm5, xmm4
+ pslldq xmm5, 4
+ shufps xmm6, xmm1, 11110000b
+ pxor xmm6, xmm5
+ pxor xmm4, xmm6
+ pshufd xmm7, xmm4, 00001110b
+ movdqu [rdx+%1], xmm7
+%endmacro
+
+
+section .rodata
+align 16
+shuffle_mask:
+DD 0FFFFFFFFh
+DD 03020100h
+DD 07060504h
+DD 0B0A0908h
+
+
+
+section .text
+
+align 16
+key_expansion256:
+
+ pshufd xmm2, xmm2, 011111111b
+
+ movdqa xmm4, xmm1
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pxor xmm1, xmm2
+
+ movdqu [rdx], xmm1
+ add rdx, 0x10
+
+ aeskeygenassist xmm4, xmm1, 0
+ pshufd xmm2, xmm4, 010101010b
+
+ movdqa xmm4, xmm3
+ pshufb xmm4, xmm5
+ pxor xmm3, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm3, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm3, xmm4
+ pxor xmm3, xmm2
+
+ movdqu [rdx], xmm3
+ add rdx, 0x10
+
+ ret
+
+
+
+align 16
+key_expansion128:
+ pshufd xmm2, xmm2, 0xFF;
+ movdqa xmm3, xmm1
+ pshufb xmm3, xmm5
+ pxor xmm1, xmm3
+ pshufb xmm3, xmm5
+ pxor xmm1, xmm3
+ pshufb xmm3, xmm5
+ pxor xmm1, xmm3
+ pxor xmm1, xmm2
+
+ ; storing the result in the key schedule array
+ movdqu [rdx], xmm1
+ add rdx, 0x10
+ ret
+
+
+
+
+
+
+align 16
+global iEncExpandKey128
+iEncExpandKey128:
+
+ linux_setup
+
+ movdqu xmm1, [rcx] ; loading the key
+
+ movdqu [rdx], xmm1
+
+ movdqa xmm5, [shuffle_mask wrt rip]
+
+ add rdx,16
+
+ aeskeygenassist xmm2, xmm1, 0x1 ; Generating round key 1
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x2 ; Generating round key 2
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x4 ; Generating round key 3
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x8 ; Generating round key 4
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x10 ; Generating round key 5
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x20 ; Generating round key 6
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x40 ; Generating round key 7
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x80 ; Generating round key 8
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x1b ; Generating round key 9
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x36 ; Generating round key 10
+ call key_expansion128
+
+ ret
+
+
+
+align 16
+global iDecExpandKey128
+iDecExpandKey128:
+
+ linux_setup
+ push rcx
+ push rdx
+ sub rsp,16+8
+
+ call iEncExpandKey128
+
+ add rsp,16+8
+ pop rdx
+ pop rcx
+
+ inversekey [rdx + 1*16]
+ inversekey [rdx + 2*16]
+ inversekey [rdx + 3*16]
+ inversekey [rdx + 4*16]
+ inversekey [rdx + 5*16]
+ inversekey [rdx + 6*16]
+ inversekey [rdx + 7*16]
+ inversekey [rdx + 8*16]
+ inversekey [rdx + 9*16]
+
+ ret
+
+
+
+align 16
+global iDecExpandKey256
+iDecExpandKey256:
+
+ linux_setup
+ push rcx
+ push rdx
+ sub rsp,16+8
+
+ call iEncExpandKey256
+
+ add rsp,16+8
+ pop rdx
+ pop rcx
+
+ inversekey [rdx + 1*16]
+ inversekey [rdx + 2*16]
+ inversekey [rdx + 3*16]
+ inversekey [rdx + 4*16]
+ inversekey [rdx + 5*16]
+ inversekey [rdx + 6*16]
+ inversekey [rdx + 7*16]
+ inversekey [rdx + 8*16]
+ inversekey [rdx + 9*16]
+ inversekey [rdx + 10*16]
+ inversekey [rdx + 11*16]
+ inversekey [rdx + 12*16]
+ inversekey [rdx + 13*16]
+
+ ret
+
+
+
+
+align 16
+global iEncExpandKey256
+iEncExpandKey256:
+
+ linux_setup
+
+ movdqu xmm1, [rcx] ; loading the key
+ movdqu xmm3, [rcx+16]
+ movdqu [rdx], xmm1 ; Storing key in memory where all key schedule will be stored
+ movdqu [rdx+16], xmm3
+
+ add rdx,32
+
+ movdqa xmm5, [shuffle_mask wrt rip] ; this mask is used by key_expansion
+
+ aeskeygenassist xmm2, xmm3, 0x1 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x2 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x4 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x8 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x10 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x20 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x40 ;
+; call key_expansion256
+
+ pshufd xmm2, xmm2, 011111111b
+
+ movdqa xmm4, xmm1
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pxor xmm1, xmm2
+
+ movdqu [rdx], xmm1
+
+
+ ret
+
+
+
+align 16
+global iDec128_CBC
+iDec128_CBC:
+
+ linux_setup
+ sub rsp,16*16+8
+
+ mov r9,rcx
+ mov rax,[rcx+24]
+ movdqu xmm5,[rax]
+
+ mov eax,[rcx+32] ; numblocks
+ mov rdx,[rcx]
+ mov r8,[rcx+8]
+ mov rcx,[rcx+16]
+
+
+ sub r8,rdx
+
+
+ test eax,eax
+ jz end_dec128_CBC
+
+ cmp eax,4
+ jl lp128decsingle_CBC
+
+ test rcx,0xf
+ jz lp128decfour_CBC
+
+ copy_round_keys rsp,rcx,0
+ copy_round_keys rsp,rcx,1
+ copy_round_keys rsp,rcx,2
+ copy_round_keys rsp,rcx,3
+ copy_round_keys rsp,rcx,4
+ copy_round_keys rsp,rcx,5
+ copy_round_keys rsp,rcx,6
+ copy_round_keys rsp,rcx,7
+ copy_round_keys rsp,rcx,8
+ copy_round_keys rsp,rcx,9
+ copy_round_keys rsp,rcx,10
+ mov rcx,rsp
+
+
+align 16
+lp128decfour_CBC:
+
+ test eax,eax
+ jz end_dec128_CBC
+
+ cmp eax,4
+ jl lp128decsingle_CBC
+
+ load_and_xor4 rdx, [rcx+10*16]
+ add rdx,16*4
+ aesdec4 [rcx+9*16]
+ aesdec4 [rcx+8*16]
+ aesdec4 [rcx+7*16]
+ aesdec4 [rcx+6*16]
+ aesdec4 [rcx+5*16]
+ aesdec4 [rcx+4*16]
+ aesdec4 [rcx+3*16]
+ aesdec4 [rcx+2*16]
+ aesdec4 [rcx+1*16]
+ aesdeclast4 [rcx+0*16]
+
+ pxor xmm0,xmm5
+ movdqu xmm4,[rdx - 16*4 + 0*16]
+ pxor xmm1,xmm4
+ movdqu xmm4,[rdx - 16*4 + 1*16]
+ pxor xmm2,xmm4
+ movdqu xmm4,[rdx - 16*4 + 2*16]
+ pxor xmm3,xmm4
+ movdqu xmm5,[rdx - 16*4 + 3*16]
+
+ sub eax,4
+ store4 r8+rdx-(16*4)
+ jmp lp128decfour_CBC
+
+
+ align 16
+lp128decsingle_CBC:
+
+ movdqu xmm0, [rdx]
+ movdqa xmm1,xmm0
+ movdqu xmm4,[rcx+10*16]
+ pxor xmm0, xmm4
+ aesdec1_u [rcx+9*16]
+ aesdec1_u [rcx+8*16]
+ aesdec1_u [rcx+7*16]
+ aesdec1_u [rcx+6*16]
+ aesdec1_u [rcx+5*16]
+ aesdec1_u [rcx+4*16]
+ aesdec1_u [rcx+3*16]
+ aesdec1_u [rcx+2*16]
+ aesdec1_u [rcx+1*16]
+ aesdeclast1_u [rcx+0*16]
+
+ pxor xmm0,xmm5
+ movdqa xmm5,xmm1
+ add rdx, 16
+ movdqu [r8 + rdx - 16], xmm0
+ dec eax
+ jnz lp128decsingle_CBC
+
+end_dec128_CBC:
+
+ mov r9,[r9+24]
+ movdqu [r9],xmm5
+ add rsp,16*16+8
+ ret
+
+
+
+align 16
+global iDec256_CBC
+iDec256_CBC:
+
+ linux_setup
+ sub rsp,16*16+8
+
+ mov r9,rcx
+ mov rax,[rcx+24]
+ movdqu xmm5,[rax]
+
+ mov eax,[rcx+32] ; numblocks
+ mov rdx,[rcx]
+ mov r8,[rcx+8]
+ mov rcx,[rcx+16]
+
+
+ sub r8,rdx
+
+ test eax,eax
+ jz end_dec256_CBC
+
+ cmp eax,4
+ jl lp256decsingle_CBC
+
+ test rcx,0xf
+ jz lp256decfour_CBC
+
+ copy_round_keys rsp,rcx,0
+ copy_round_keys rsp,rcx,1
+ copy_round_keys rsp,rcx,2
+ copy_round_keys rsp,rcx,3
+ copy_round_keys rsp,rcx,4
+ copy_round_keys rsp,rcx,5
+ copy_round_keys rsp,rcx,6
+ copy_round_keys rsp,rcx,7
+ copy_round_keys rsp,rcx,8
+ copy_round_keys rsp,rcx,9
+ copy_round_keys rsp,rcx,10
+ copy_round_keys rsp,rcx,11
+ copy_round_keys rsp,rcx,12
+ copy_round_keys rsp,rcx,13
+ copy_round_keys rsp,rcx,14
+ mov rcx,rsp
+
+align 16
+lp256decfour_CBC:
+
+ test eax,eax
+ jz end_dec256_CBC
+
+ cmp eax,4
+ jl lp256decsingle_CBC
+
+ load_and_xor4 rdx, [rcx+14*16]
+ add rdx,16*4
+ aesdec4 [rcx+13*16]
+ aesdec4 [rcx+12*16]
+ aesdec4 [rcx+11*16]
+ aesdec4 [rcx+10*16]
+ aesdec4 [rcx+9*16]
+ aesdec4 [rcx+8*16]
+ aesdec4 [rcx+7*16]
+ aesdec4 [rcx+6*16]
+ aesdec4 [rcx+5*16]
+ aesdec4 [rcx+4*16]
+ aesdec4 [rcx+3*16]
+ aesdec4 [rcx+2*16]
+ aesdec4 [rcx+1*16]
+ aesdeclast4 [rcx+0*16]
+
+ pxor xmm0,xmm5
+ movdqu xmm4,[rdx - 16*4 + 0*16]
+ pxor xmm1,xmm4
+ movdqu xmm4,[rdx - 16*4 + 1*16]
+ pxor xmm2,xmm4
+ movdqu xmm4,[rdx - 16*4 + 2*16]
+ pxor xmm3,xmm4
+ movdqu xmm5,[rdx - 16*4 + 3*16]
+
+ sub eax,4
+ store4 r8+rdx-(16*4)
+ jmp lp256decfour_CBC
+
+
+ align 16
+lp256decsingle_CBC:
+
+ movdqu xmm0, [rdx]
+ movdqu xmm4,[rcx+14*16]
+ movdqa xmm1,xmm0
+ pxor xmm0, xmm4
+ aesdec1_u [rcx+13*16]
+ aesdec1_u [rcx+12*16]
+ aesdec1_u [rcx+11*16]
+ aesdec1_u [rcx+10*16]
+ aesdec1_u [rcx+9*16]
+ aesdec1_u [rcx+8*16]
+ aesdec1_u [rcx+7*16]
+ aesdec1_u [rcx+6*16]
+ aesdec1_u [rcx+5*16]
+ aesdec1_u [rcx+4*16]
+ aesdec1_u [rcx+3*16]
+ aesdec1_u [rcx+2*16]
+ aesdec1_u [rcx+1*16]
+ aesdeclast1_u [rcx+0*16]
+
+ pxor xmm0,xmm5
+ movdqa xmm5,xmm1
+ add rdx, 16
+ movdqu [r8 + rdx - 16], xmm0
+ dec eax
+ jnz lp256decsingle_CBC
+
+end_dec256_CBC:
+
+ mov r9,[r9+24]
+ movdqu [r9],xmm5
+ add rsp,16*16+8
+ ret
+
+
+
+align 16
+global iEnc128_CBC
+iEnc128_CBC:
+
+ linux_setup
+ sub rsp,16*16+8
+
+ mov r9,rcx
+ mov rax,[rcx+24]
+ movdqu xmm1,[rax]
+
+ mov eax,[rcx+32] ; numblocks
+ mov rdx,[rcx]
+ mov r8,[rcx+8]
+ mov rcx,[rcx+16]
+
+ sub r8,rdx
+
+
+ test rcx,0xf
+ jz lp128encsingle_CBC
+
+ copy_round_keys rsp,rcx,0
+ copy_round_keys rsp,rcx,1
+ copy_round_keys rsp,rcx,2
+ copy_round_keys rsp,rcx,3
+ copy_round_keys rsp,rcx,4
+ copy_round_keys rsp,rcx,5
+ copy_round_keys rsp,rcx,6
+ copy_round_keys rsp,rcx,7
+ copy_round_keys rsp,rcx,8
+ copy_round_keys rsp,rcx,9
+ copy_round_keys rsp,rcx,10
+ mov rcx,rsp
+
+
+ align 16
+
+lp128encsingle_CBC:
+
+ movdqu xmm0, [rdx]
+ movdqu xmm4,[rcx+0*16]
+ add rdx, 16
+ pxor xmm0, xmm1
+ pxor xmm0, xmm4
+ aesenc1 [rcx+1*16]
+ aesenc1 [rcx+2*16]
+ aesenc1 [rcx+3*16]
+ aesenc1 [rcx+4*16]
+ aesenc1 [rcx+5*16]
+ aesenc1 [rcx+6*16]
+ aesenc1 [rcx+7*16]
+ aesenc1 [rcx+8*16]
+ aesenc1 [rcx+9*16]
+ aesenclast1 [rcx+10*16]
+ movdqa xmm1,xmm0
+
+ ; Store output encrypted data into CIPHERTEXT array
+ movdqu [r8+rdx-16], xmm0
+ dec eax
+ jnz lp128encsingle_CBC
+
+ mov r9,[r9+24]
+ movdqu [r9],xmm1
+ add rsp,16*16+8
+ ret
+
+
+
+align 16
+global iEnc256_CBC
+iEnc256_CBC:
+
+ linux_setup
+ sub rsp,16*16+8
+
+ mov r9,rcx
+ mov rax,[rcx+24]
+ movdqu xmm1,[rax]
+
+ mov eax,[rcx+32] ; numblocks
+ mov rdx,[rcx]
+ mov r8,[rcx+8]
+ mov rcx,[rcx+16]
+
+ sub r8,rdx
+
+ test rcx,0xf
+ jz lp256encsingle_CBC
+
+ copy_round_keys rsp,rcx,0
+ copy_round_keys rsp,rcx,1
+ copy_round_keys rsp,rcx,2
+ copy_round_keys rsp,rcx,3
+ copy_round_keys rsp,rcx,4
+ copy_round_keys rsp,rcx,5
+ copy_round_keys rsp,rcx,6
+ copy_round_keys rsp,rcx,7
+ copy_round_keys rsp,rcx,8
+ copy_round_keys rsp,rcx,9
+ copy_round_keys rsp,rcx,10
+ copy_round_keys rsp,rcx,11
+ copy_round_keys rsp,rcx,12
+ copy_round_keys rsp,rcx,13
+ copy_round_keys rsp,rcx,14
+ mov rcx,rsp
+
+ align 16
+
+lp256encsingle_CBC:
+
+ movdqu xmm0, [rdx]
+ movdqu xmm4, [rcx+0*16]
+ add rdx, 16
+ pxor xmm0, xmm1
+ pxor xmm0, xmm4
+ aesenc1 [rcx+1*16]
+ aesenc1 [rcx+2*16]
+ aesenc1 [rcx+3*16]
+ aesenc1 [rcx+4*16]
+ aesenc1 [rcx+5*16]
+ aesenc1 [rcx+6*16]
+ aesenc1 [rcx+7*16]
+ aesenc1 [rcx+8*16]
+ aesenc1 [rcx+9*16]
+ aesenc1 [rcx+10*16]
+ aesenc1 [rcx+11*16]
+ aesenc1 [rcx+12*16]
+ aesenc1 [rcx+13*16]
+ aesenclast1 [rcx+14*16]
+ movdqa xmm1,xmm0
+
+ ; Store output encrypted data into CIPHERTEXT array
+ movdqu [r8+rdx-16], xmm0
+ dec eax
+ jnz lp256encsingle_CBC
+
+ mov r9,[r9+24]
+ movdqu [r9],xmm1
+ add rsp,16*16+8
+ ret
+
+; Mark this file as not needing an executable stack.
+%ifidn __OUTPUT_FORMAT__,elf
+section .note.GNU-stack noalloc noexec nowrite progbits
+%endif
+%ifidn __OUTPUT_FORMAT__,elf32
+section .note.GNU-stack noalloc noexec nowrite progbits
+%endif
+%ifidn __OUTPUT_FORMAT__,elf64
+section .note.GNU-stack noalloc noexec nowrite progbits
+%endif
diff --git a/src/lib/crypto/builtin/aes/iaesx86.s b/src/lib/crypto/builtin/aes/iaesx86.s
new file mode 100644
index 000000000000..945942c06413
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/iaesx86.s
@@ -0,0 +1,842 @@
+[bits 32]
+[CPU intelnop]
+
+; Copyright (c) 2010, Intel Corporation
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are met:
+;
+; * Redistributions of source code must retain the above copyright notice,
+; this list of conditions and the following disclaimer.
+; * Redistributions in binary form must reproduce the above copyright notice,
+; this list of conditions and the following disclaimer in the documentation
+; and/or other materials provided with the distribution.
+; * Neither the name of Intel Corporation nor the names of its contributors
+; may be used to endorse or promote products derived from this software
+; without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+; IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+%define _iEncExpandKey128 k5_iEncExpandKey128
+%define _iEncExpandKey256 k5_iEncExpandKey256
+%define _iDecExpandKey128 k5_iDecExpandKey128
+%define _iDecExpandKey256 k5_iDecExpandKey256
+%define _iEnc128_CBC k5_iEnc128_CBC
+%define _iEnc256_CBC k5_iEnc256_CBC
+%define _iDec128_CBC k5_iDec128_CBC
+%define _iDec256_CBC k5_iDec256_CBC
+
+%macro inversekey 1
+ movdqu xmm1,%1
+ aesimc xmm0,xmm1
+ movdqu %1,xmm0
+%endmacro
+
+
+%macro aesdec4 1
+ movdqa xmm4,%1
+
+ aesdec xmm0,xmm4
+ aesdec xmm1,xmm4
+ aesdec xmm2,xmm4
+ aesdec xmm3,xmm4
+
+%endmacro
+
+
+%macro aesdeclast4 1
+ movdqa xmm4,%1
+
+ aesdeclast xmm0,xmm4
+ aesdeclast xmm1,xmm4
+ aesdeclast xmm2,xmm4
+ aesdeclast xmm3,xmm4
+
+%endmacro
+
+
+%macro aesenc4 1
+ movdqa xmm4,%1
+
+ aesenc xmm0,xmm4
+ aesenc xmm1,xmm4
+ aesenc xmm2,xmm4
+ aesenc xmm3,xmm4
+
+%endmacro
+
+%macro aesenclast4 1
+ movdqa xmm4,%1
+
+ aesenclast xmm0,xmm4
+ aesenclast xmm1,xmm4
+ aesenclast xmm2,xmm4
+ aesenclast xmm3,xmm4
+
+%endmacro
+
+
+%macro aesdeclast1 1
+ aesdeclast xmm0,%1
+%endmacro
+
+%macro aesenclast1 1
+ aesenclast xmm0,%1
+%endmacro
+
+%macro aesdec1 1
+ aesdec xmm0,%1
+%endmacro
+
+;abab
+%macro aesenc1 1
+ aesenc xmm0,%1
+%endmacro
+
+
+%macro aesdeclast1_u 1
+ movdqu xmm4,%1
+ aesdeclast xmm0,xmm4
+%endmacro
+
+%macro aesenclast1_u 1
+ movdqu xmm4,%1
+ aesenclast xmm0,xmm4
+%endmacro
+
+%macro aesdec1_u 1
+ movdqu xmm4,%1
+ aesdec xmm0,xmm4
+%endmacro
+
+%macro aesenc1_u 1
+ movdqu xmm4,%1
+ aesenc xmm0,xmm4
+%endmacro
+
+
+%macro load_and_xor4 2
+ movdqa xmm4,%2
+ movdqu xmm0,[%1 + 0*16]
+ pxor xmm0,xmm4
+ movdqu xmm1,[%1 + 1*16]
+ pxor xmm1,xmm4
+ movdqu xmm2,[%1 + 2*16]
+ pxor xmm2,xmm4
+ movdqu xmm3,[%1 + 3*16]
+ pxor xmm3,xmm4
+%endmacro
+
+
+%macro xor_with_input4 1
+ movdqu xmm4,[%1]
+ pxor xmm0,xmm4
+ movdqu xmm4,[%1+16]
+ pxor xmm1,xmm4
+ movdqu xmm4,[%1+32]
+ pxor xmm2,xmm4
+ movdqu xmm4,[%1+48]
+ pxor xmm3,xmm4
+%endmacro
+
+%macro store4 1
+ movdqu [%1 + 0*16],xmm0
+ movdqu [%1 + 1*16],xmm1
+ movdqu [%1 + 2*16],xmm2
+ movdqu [%1 + 3*16],xmm3
+%endmacro
+
+
+%macro copy_round_keys 3
+ movdqu xmm4,[%2 + ((%3)*16)]
+ movdqa [%1 + ((%3)*16)],xmm4
+%endmacro
+
+;abab
+%macro copy_round_keyx 3
+ movdqu xmm4,[%2 + ((%3)*16)]
+ movdqa %1,xmm4
+%endmacro
+
+
+
+%macro key_expansion_1_192 1
+ ;; Assumes the xmm3 includes all zeros at this point.
+ pshufd xmm2, xmm2, 11111111b
+ shufps xmm3, xmm1, 00010000b
+ pxor xmm1, xmm3
+ shufps xmm3, xmm1, 10001100b
+ pxor xmm1, xmm3
+ pxor xmm1, xmm2
+ movdqu [edx+%1], xmm1
+%endmacro
+
+; Calculate w10 and w11 using calculated w9 and known w4-w5
+%macro key_expansion_2_192 1
+ movdqa xmm5, xmm4
+ pslldq xmm5, 4
+ shufps xmm6, xmm1, 11110000b
+ pxor xmm6, xmm5
+ pxor xmm4, xmm6
+ pshufd xmm7, xmm4, 00001110b
+ movdqu [edx+%1], xmm7
+%endmacro
+
+
+
+
+
+section .rodata
+align 16
+shuffle_mask:
+DD 0FFFFFFFFh
+DD 03020100h
+DD 07060504h
+DD 0B0A0908h
+
+
+section .text
+
+
+
+align 16
+key_expansion256:
+
+ pshufd xmm2, xmm2, 011111111b
+
+ movdqu xmm4, xmm1
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pxor xmm1, xmm2
+
+ movdqu [edx], xmm1
+ add edx, 0x10
+
+ aeskeygenassist xmm4, xmm1, 0
+ pshufd xmm2, xmm4, 010101010b
+
+ movdqu xmm4, xmm3
+ pshufb xmm4, xmm5
+ pxor xmm3, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm3, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm3, xmm4
+ pxor xmm3, xmm2
+
+ movdqu [edx], xmm3
+ add edx, 0x10
+
+ ret
+
+
+
+align 16
+key_expansion128:
+ pshufd xmm2, xmm2, 0xFF;
+ movdqu xmm3, xmm1
+ pshufb xmm3, xmm5
+ pxor xmm1, xmm3
+ pshufb xmm3, xmm5
+ pxor xmm1, xmm3
+ pshufb xmm3, xmm5
+ pxor xmm1, xmm3
+ pxor xmm1, xmm2
+
+ ; storing the result in the key schedule array
+ movdqu [edx], xmm1
+ add edx, 0x10
+ ret
+
+
+
+align 16
+global _iEncExpandKey128
+_iEncExpandKey128:
+
+ mov ecx,[esp-4+8] ;input
+ mov edx,[esp-4+12] ;ctx
+
+ movdqu xmm1, [ecx] ; loading the key
+
+ movdqu [edx], xmm1
+
+ call .next
+.next:
+ pop ecx
+ movdqa xmm5, [ecx-.next+shuffle_mask]
+
+ add edx,16
+
+ aeskeygenassist xmm2, xmm1, 0x1 ; Generating round key 1
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x2 ; Generating round key 2
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x4 ; Generating round key 3
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x8 ; Generating round key 4
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x10 ; Generating round key 5
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x20 ; Generating round key 6
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x40 ; Generating round key 7
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x80 ; Generating round key 8
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x1b ; Generating round key 9
+ call key_expansion128
+ aeskeygenassist xmm2, xmm1, 0x36 ; Generating round key 10
+ call key_expansion128
+
+ ret
+
+
+
+align 16
+global _iDecExpandKey128
+_iDecExpandKey128:
+ push DWORD [esp+8]
+ push DWORD [esp+8]
+
+ call _iEncExpandKey128
+ add esp,8
+
+ mov edx,[esp-4+12] ;ctx
+
+ inversekey [edx + 1*16]
+ inversekey [edx + 2*16]
+ inversekey [edx + 3*16]
+ inversekey [edx + 4*16]
+ inversekey [edx + 5*16]
+ inversekey [edx + 6*16]
+ inversekey [edx + 7*16]
+ inversekey [edx + 8*16]
+ inversekey [edx + 9*16]
+
+ ret
+
+
+
+align 16
+global _iDecExpandKey256
+_iDecExpandKey256:
+ push DWORD [esp+8]
+ push DWORD [esp+8]
+
+ call _iEncExpandKey256
+ add esp, 8
+
+ mov edx, [esp-4+12] ;expanded key
+
+ inversekey [edx + 1*16]
+ inversekey [edx + 2*16]
+ inversekey [edx + 3*16]
+ inversekey [edx + 4*16]
+ inversekey [edx + 5*16]
+ inversekey [edx + 6*16]
+ inversekey [edx + 7*16]
+ inversekey [edx + 8*16]
+ inversekey [edx + 9*16]
+ inversekey [edx + 10*16]
+ inversekey [edx + 11*16]
+ inversekey [edx + 12*16]
+ inversekey [edx + 13*16]
+
+ ret
+
+
+
+
+align 16
+global _iEncExpandKey256
+_iEncExpandKey256:
+ mov ecx, [esp-4+8] ;input
+ mov edx, [esp-4+12] ;expanded key
+
+
+ movdqu xmm1, [ecx] ; loading the key
+ movdqu xmm3, [ecx+16]
+ movdqu [edx], xmm1 ; Storing key in memory where all key schedule will be stored
+ movdqu [edx+16], xmm3
+
+ add edx,32
+
+ call .next
+.next:
+ pop ecx
+ movdqa xmm5, [ecx-.next+shuffle_mask] ; this mask is used by key_expansion
+
+ aeskeygenassist xmm2, xmm3, 0x1 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x2 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x4 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x8 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x10 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x20 ;
+ call key_expansion256
+ aeskeygenassist xmm2, xmm3, 0x40 ;
+; call key_expansion256
+
+ pshufd xmm2, xmm2, 011111111b
+
+ movdqu xmm4, xmm1
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pshufb xmm4, xmm5
+ pxor xmm1, xmm4
+ pxor xmm1, xmm2
+
+ movdqu [edx], xmm1
+
+
+ ret
+
+
+
+align 16
+global _iDec128_CBC
+_iDec128_CBC:
+ mov ecx,[esp-4+8]
+
+ push esi
+ push edi
+ push ebp
+ mov ebp,esp
+ sub esp,16*16
+ and esp,0xfffffff0
+
+ mov eax,[ecx+12]
+ movdqu xmm5,[eax] ;iv
+
+ mov eax,[ecx+16] ; numblocks
+ mov esi,[ecx]
+ mov edi,[ecx+4]
+ mov ecx,[ecx+8]
+
+ sub edi,esi
+
+ test eax,eax
+ jz end_dec128_CBC
+
+ cmp eax,4
+ jl lp128decsingle_CBC
+
+ test ecx,0xf
+ jz lp128decfour_CBC
+
+ copy_round_keys esp,ecx,0
+ copy_round_keys esp,ecx,1
+ copy_round_keys esp,ecx,2
+ copy_round_keys esp,ecx,3
+ copy_round_keys esp,ecx,4
+ copy_round_keys esp,ecx,5
+ copy_round_keys esp,ecx,6
+ copy_round_keys esp,ecx,7
+ copy_round_keys esp,ecx,8
+ copy_round_keys esp,ecx,9
+ copy_round_keys esp,ecx,10
+ mov ecx,esp
+
+
+align 16
+lp128decfour_CBC:
+
+ test eax,eax
+ jz end_dec128_CBC
+
+ cmp eax,4
+ jl lp128decsingle_CBC
+
+ load_and_xor4 esi, [ecx+10*16]
+ add esi,16*4
+ aesdec4 [ecx+9*16]
+ aesdec4 [ecx+8*16]
+ aesdec4 [ecx+7*16]
+ aesdec4 [ecx+6*16]
+ aesdec4 [ecx+5*16]
+ aesdec4 [ecx+4*16]
+ aesdec4 [ecx+3*16]
+ aesdec4 [ecx+2*16]
+ aesdec4 [ecx+1*16]
+ aesdeclast4 [ecx+0*16]
+
+ pxor xmm0,xmm5
+ movdqu xmm4,[esi- 16*4 + 0*16]
+ pxor xmm1,xmm4
+ movdqu xmm4,[esi- 16*4 + 1*16]
+ pxor xmm2,xmm4
+ movdqu xmm4,[esi- 16*4 + 2*16]
+ pxor xmm3,xmm4
+ movdqu xmm5,[esi- 16*4 + 3*16]
+
+ sub eax,4
+ store4 esi+edi-(16*4)
+ jmp lp128decfour_CBC
+
+
+ align 16
+lp128decsingle_CBC:
+
+ movdqu xmm0, [esi]
+ movdqa xmm1,xmm0
+ movdqu xmm4,[ecx+10*16]
+ pxor xmm0, xmm4
+ aesdec1_u [ecx+9*16]
+ aesdec1_u [ecx+8*16]
+ aesdec1_u [ecx+7*16]
+ aesdec1_u [ecx+6*16]
+ aesdec1_u [ecx+5*16]
+ aesdec1_u [ecx+4*16]
+ aesdec1_u [ecx+3*16]
+ aesdec1_u [ecx+2*16]
+ aesdec1_u [ecx+1*16]
+ aesdeclast1_u [ecx+0*16]
+
+ pxor xmm0,xmm5
+ movdqa xmm5,xmm1
+
+ add esi, 16
+ movdqu [edi+esi - 16], xmm0
+ dec eax
+ jnz lp128decsingle_CBC
+
+end_dec128_CBC:
+
+ mov esp,ebp
+ pop ebp
+ pop edi
+ pop esi
+
+ mov ecx,[esp-4+8] ; first arg
+ mov ecx,[ecx+12]
+ movdqu [ecx],xmm5 ; store last iv for chaining
+
+ ret
+
+
+
+align 16
+global _iDec256_CBC
+_iDec256_CBC:
+ mov ecx,[esp-4+8]
+
+ push esi
+ push edi
+ push ebp
+ mov ebp,esp
+
+ sub esp,16*16
+ and esp,0xfffffff0
+
+ mov eax,[ecx+12]
+ movdqu xmm5,[eax] ;iv
+
+ mov eax,[ecx+16] ; numblocks
+ mov esi,[ecx]
+ mov edi,[ecx+4]
+ mov ecx,[ecx+8]
+
+ sub edi,esi
+
+ test eax,eax
+ jz end_dec256_CBC
+
+ cmp eax,4
+ jl lp256decsingle_CBC
+
+ test ecx,0xf
+ jz lp256decfour_CBC
+
+ copy_round_keys esp,ecx,0
+ copy_round_keys esp,ecx,1
+ copy_round_keys esp,ecx,2
+ copy_round_keys esp,ecx,3
+ copy_round_keys esp,ecx,4
+ copy_round_keys esp,ecx,5
+ copy_round_keys esp,ecx,6
+ copy_round_keys esp,ecx,7
+ copy_round_keys esp,ecx,8
+ copy_round_keys esp,ecx,9
+ copy_round_keys esp,ecx,10
+ copy_round_keys esp,ecx,11
+ copy_round_keys esp,ecx,12
+ copy_round_keys esp,ecx,13
+ copy_round_keys esp,ecx,14
+ mov ecx,esp
+
+align 16
+lp256decfour_CBC:
+
+ test eax,eax
+ jz end_dec256_CBC
+
+ cmp eax,4
+ jl lp256decsingle_CBC
+
+ load_and_xor4 esi, [ecx+14*16]
+ add esi,16*4
+ aesdec4 [ecx+13*16]
+ aesdec4 [ecx+12*16]
+ aesdec4 [ecx+11*16]
+ aesdec4 [ecx+10*16]
+ aesdec4 [ecx+9*16]
+ aesdec4 [ecx+8*16]
+ aesdec4 [ecx+7*16]
+ aesdec4 [ecx+6*16]
+ aesdec4 [ecx+5*16]
+ aesdec4 [ecx+4*16]
+ aesdec4 [ecx+3*16]
+ aesdec4 [ecx+2*16]
+ aesdec4 [ecx+1*16]
+ aesdeclast4 [ecx+0*16]
+
+ pxor xmm0,xmm5
+ movdqu xmm4,[esi- 16*4 + 0*16]
+ pxor xmm1,xmm4
+ movdqu xmm4,[esi- 16*4 + 1*16]
+ pxor xmm2,xmm4
+ movdqu xmm4,[esi- 16*4 + 2*16]
+ pxor xmm3,xmm4
+ movdqu xmm5,[esi- 16*4 + 3*16]
+
+ sub eax,4
+ store4 esi+edi-(16*4)
+ jmp lp256decfour_CBC
+
+
+ align 16
+lp256decsingle_CBC:
+
+ movdqu xmm0, [esi]
+ movdqa xmm1,xmm0
+ movdqu xmm4, [ecx+14*16]
+ pxor xmm0, xmm4
+ aesdec1_u [ecx+13*16]
+ aesdec1_u [ecx+12*16]
+ aesdec1_u [ecx+11*16]
+ aesdec1_u [ecx+10*16]
+ aesdec1_u [ecx+9*16]
+ aesdec1_u [ecx+8*16]
+ aesdec1_u [ecx+7*16]
+ aesdec1_u [ecx+6*16]
+ aesdec1_u [ecx+5*16]
+ aesdec1_u [ecx+4*16]
+ aesdec1_u [ecx+3*16]
+ aesdec1_u [ecx+2*16]
+ aesdec1_u [ecx+1*16]
+ aesdeclast1_u [ecx+0*16]
+
+ pxor xmm0,xmm5
+ movdqa xmm5,xmm1
+
+ add esi, 16
+ movdqu [edi+esi - 16], xmm0
+ dec eax
+ jnz lp256decsingle_CBC
+
+end_dec256_CBC:
+
+
+ mov esp,ebp
+ pop ebp
+ pop edi
+ pop esi
+
+ mov ecx,[esp-4+8] ; first arg
+ mov ecx,[ecx+12]
+ movdqu [ecx],xmm5 ; store last iv for chaining
+
+ ret
+
+
+
+align 16
+global _iEnc128_CBC
+_iEnc128_CBC:
+ mov ecx,[esp-4+8]
+
+ push esi
+ push edi
+ push ebp
+ mov ebp,esp
+
+ sub esp,16*16
+ and esp,0xfffffff0
+
+ mov eax,[ecx+12]
+ movdqu xmm1,[eax] ;iv
+
+ mov eax,[ecx+16] ; numblocks
+ mov esi,[ecx]
+ mov edi,[ecx+4]
+ mov ecx,[ecx+8]
+ sub edi,esi
+
+ test ecx,0xf
+ jz lp128encsingle_CBC
+
+ copy_round_keys esp,ecx,0
+ copy_round_keys esp,ecx,1
+ copy_round_keys esp,ecx,2
+ copy_round_keys esp,ecx,3
+ copy_round_keys esp,ecx,4
+ copy_round_keys esp,ecx,5
+ copy_round_keys esp,ecx,6
+ copy_round_keys esp,ecx,7
+ copy_round_keys esp,ecx,8
+ copy_round_keys esp,ecx,9
+ copy_round_keys esp,ecx,10
+ mov ecx,esp
+
+ align 16
+
+lp128encsingle_CBC:
+
+ movdqu xmm0, [esi]
+ add esi, 16
+ pxor xmm0, xmm1
+ movdqu xmm4,[ecx+0*16]
+ pxor xmm0, xmm4
+ aesenc1 [ecx+1*16]
+ aesenc1 [ecx+2*16]
+ aesenc1 [ecx+3*16]
+ aesenc1 [ecx+4*16]
+ aesenc1 [ecx+5*16]
+ aesenc1 [ecx+6*16]
+ aesenc1 [ecx+7*16]
+ aesenc1 [ecx+8*16]
+ aesenc1 [ecx+9*16]
+ aesenclast1 [ecx+10*16]
+ ; Store output encrypted data into CIPHERTEXT array
+ movdqu [esi+edi-16], xmm0
+ movdqa xmm1,xmm0
+ dec eax
+ jnz lp128encsingle_CBC
+
+
+ mov esp,ebp
+ pop ebp
+ pop edi
+ pop esi
+ mov ecx,[esp-4+8] ; first arg
+ mov ecx,[ecx+12]
+ movdqu [ecx],xmm1 ; store last iv for chaining
+
+ ret
+
+
+
+align 16
+global _iEnc256_CBC
+_iEnc256_CBC:
+ mov ecx,[esp-4+8] ; first arg
+
+ push esi
+ push edi
+ push ebp
+ mov ebp,esp
+
+ sub esp,16*16
+ and esp,0xfffffff0
+
+ mov eax,[ecx+12]
+ movdqu xmm1,[eax] ;iv
+
+ mov eax,[ecx+16] ; numblocks
+ mov esi,[ecx]
+ mov edi,[ecx+4]
+ mov ecx,[ecx+8]
+ sub edi,esi
+
+ test ecx,0xf
+ jz lp256encsingle_CBC
+
+ copy_round_keys esp,ecx,0
+ copy_round_keys esp,ecx,1
+ copy_round_keys esp,ecx,2
+ copy_round_keys esp,ecx,3
+ copy_round_keys esp,ecx,4
+ copy_round_keys esp,ecx,5
+ copy_round_keys esp,ecx,6
+ copy_round_keys esp,ecx,7
+ copy_round_keys esp,ecx,8
+ copy_round_keys esp,ecx,9
+ copy_round_keys esp,ecx,10
+ copy_round_keys esp,ecx,11
+ copy_round_keys esp,ecx,12
+ copy_round_keys esp,ecx,13
+ copy_round_keys esp,ecx,14
+ mov ecx,esp
+
+ align 16
+
+lp256encsingle_CBC:
+
+;abab
+ movdqu xmm0, [esi]
+ add esi, 16
+ pxor xmm0, xmm1
+ movdqu xmm4,[ecx+0*16]
+ pxor xmm0, xmm4
+ aesenc1 [ecx+1*16]
+ aesenc1 [ecx+2*16]
+ aesenc1 [ecx+3*16]
+ aesenc1 [ecx+4*16]
+ aesenc1 [ecx+5*16]
+ aesenc1 [ecx+6*16]
+ aesenc1 [ecx+7*16]
+ aesenc1 [ecx+8*16]
+ aesenc1 [ecx+9*16]
+ aesenc1 [ecx+10*16]
+ aesenc1 [ecx+11*16]
+ aesenc1 [ecx+12*16]
+ aesenc1 [ecx+13*16]
+ aesenclast1 [ecx+14*16]
+ ; Store output encrypted data into CIPHERTEXT array
+ movdqu [esi+edi-16], xmm0
+ movdqa xmm1,xmm0
+ dec eax
+ jnz lp256encsingle_CBC
+
+
+ mov esp,ebp
+ pop ebp
+ pop edi
+ pop esi
+ mov ecx,[esp-4+8]
+ mov ecx,[ecx+12]
+ movdqu [ecx],xmm1 ; store last iv for chaining
+
+ ret
+
+; Mark this file as not needing an executable stack.
+%ifidn __OUTPUT_FORMAT__,elf
+section .note.GNU-stack noalloc noexec nowrite progbits
+%endif
+%ifidn __OUTPUT_FORMAT__,elf32
+section .note.GNU-stack noalloc noexec nowrite progbits
+%endif
+%ifidn __OUTPUT_FORMAT__,elf64
+section .note.GNU-stack noalloc noexec nowrite progbits
+%endif
diff --git a/src/lib/crypto/builtin/camellia/Makefile.in b/src/lib/crypto/builtin/camellia/Makefile.in
new file mode 100644
index 000000000000..5d3b14cf1ce7
--- /dev/null
+++ b/src/lib/crypto/builtin/camellia/Makefile.in
@@ -0,0 +1,41 @@
+thisconfigdir=../../../..
+myfulldir=lib/crypto/builtin/camellia
+mydir=lib$(S)crypto$(S)builtin$(S)camellia
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+LOCALINCLUDES = -I$(srcdir)/../aes
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR = builtin\camellia
+##DOS##OBJFILE = ..\..\$(OUTPRE)camellia.lst
+
+STLIBOBJS= camellia.o
+
+OBJS= $(OUTPRE)camellia.$(OBJEXT)
+
+SRCS= $(srcdir)/camellia.c
+
+GEN_OBJS= $(OUTPRE)camellia.$(OBJEXT)
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix: all-libobjs # camellia-gen
+
+includes: depend
+
+depend: $(SRCS)
+
+camellia-gen: camellia-gen.o $(GEN_OBJS)
+ $(CC_LINK) -o camellia-gen camellia-gen.o $(GEN_OBJS)
+
+run-camellia-gen: camellia-gen
+ ./camellia-gen > kresults.out
+
+check: run-camellia-gen
+
+
+clean-unix:: clean-libobjs
+
+clean:
+ -$(RM) camellia-gen camellia-gen.o kresults.out
+
+@libobj_frag@
diff --git a/src/lib/crypto/builtin/camellia/camellia-gen.c b/src/lib/crypto/builtin/camellia/camellia-gen.c
new file mode 100644
index 000000000000..23b69c174129
--- /dev/null
+++ b/src/lib/crypto/builtin/camellia/camellia-gen.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2009
+ * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "camellia.h"
+
+#define B 16U
+unsigned char key[16];
+unsigned char test_case_len[] = { B+1, 2*B-1, 2*B, 2*B+1, 3*B-1, 3*B, 4*B, };
+#define NTESTS (sizeof(test_case_len))
+struct {
+ unsigned char ivec[16];
+ unsigned char input[4*16];
+ unsigned char output[4*16];
+} test_case[NTESTS];
+camellia_ctx ctx, dctx;
+
+static void init ()
+{
+ size_t i, j;
+ cam_rval r;
+
+ srand(42);
+ for (i = 0; i < 16; i++)
+ key[i] = 0xff & rand();
+ memset(test_case, 0, sizeof(test_case));
+ for (i = 0; i < NTESTS; i++)
+ for (j = 0; j < test_case_len[i]; j++) {
+ test_case[i].input[j] = 0xff & rand();
+ }
+
+ r = camellia_enc_key (key, sizeof(key), &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ r = camellia_dec_key (key, sizeof(key), &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+}
+
+static void hexdump(const unsigned char *ptr, size_t len)
+{
+ size_t i;
+ for (i = 0; i < len; i++)
+ printf ("%s%02X", (i % 16 == 0) ? "\n " : " ", ptr[i]);
+}
+
+static void fips_test ()
+{
+ static const unsigned char fipskey[16] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+ 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
+ };
+ static const unsigned char input[16] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+ 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
+ };
+ static const unsigned char expected[16] = {
+ 0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
+ 0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
+ };
+ unsigned char output[16];
+ unsigned char tmp[16];
+ camellia_ctx fipsctx;
+ int r;
+
+ printf ("FIPS test:\nkey:");
+ hexdump (fipskey, 16);
+ printf ("\ninput:");
+ hexdump (input, 16);
+ r = camellia_enc_key (fipskey, sizeof(fipskey), &fipsctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ r = camellia_enc_blk (input, output, &fipsctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ printf ("\noutput:");
+ hexdump (output, 16);
+ printf ("\n");
+ if (memcmp(expected, output, 16))
+ fprintf(stderr, "wrong results!!!\n"), exit (1);
+ r = camellia_dec_key (fipskey, sizeof(fipskey), &fipsctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ r = camellia_dec_blk (output, tmp, &fipsctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ if (memcmp(input, tmp, 16))
+ fprintf(stderr, "decryption failed!!\n"), exit(1);
+ printf ("ok.\n\n");
+}
+
+static void
+xor (unsigned char *out, const unsigned char *a, const unsigned char *b)
+{
+ size_t i;
+ for (i = 0; i < B; i++)
+ out[i] = a[i] ^ b[i];
+}
+
+static void
+ecb_enc (unsigned char *out, unsigned char *in, unsigned int len)
+{
+ size_t i;
+ cam_rval r;
+ for (i = 0; i < len; i += 16) {
+ r = camellia_enc_blk (in + i, out + i, &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ }
+ if (i != len) abort ();
+}
+
+static void
+ecb_dec (unsigned char *out, unsigned char *in, unsigned int len)
+{
+ size_t i;
+ cam_rval r;
+ for (i = 0; i < len; i += 16) {
+ r = camellia_dec_blk (in + i, out + i, &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ }
+ if (i != len) abort ();
+}
+
+#define D(X) (printf("%s %d: %s=",__FUNCTION__,__LINE__, #X),hexdump(X,B),printf("\n"))
+
+#undef D
+#define D(X)
+
+static void
+cbc_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
+ unsigned int len)
+{
+ size_t i;
+ cam_rval r;
+ unsigned char tmp[B];
+ D(iv);
+ memcpy (tmp, iv, B);
+ for (i = 0; i < len; i += B) {
+ D(in+i);
+ xor (tmp, tmp, in + i);
+ D(tmp);
+ r = camellia_enc_blk (tmp, out + i, &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ memcpy (tmp, out + i, B);
+ D(out+i);
+ }
+ if (i != len) abort ();
+}
+
+static void
+cbc_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
+ unsigned int len)
+{
+ size_t i;
+ cam_rval r;
+ unsigned char tmp[B];
+ memcpy (tmp, iv, B);
+ for (i = 0; i < len; i += B) {
+ r = camellia_dec_blk (in + i, tmp, &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ xor (tmp, tmp, iv);
+ iv = in + i;
+ memcpy (out + i, tmp, B);
+ }
+ if (i != len) abort ();
+}
+
+static void
+cts_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
+ unsigned int len)
+{
+ int r;
+ unsigned int len2;
+ unsigned char pn1[B], pn[B], cn[B], cn1[B];
+
+ if (len < B + 1) abort ();
+ len2 = (len - B - 1) & ~(B-1);
+ cbc_enc (out, in, iv, len2);
+ out += len2;
+ in += len2;
+ len -= len2;
+ if (len2)
+ iv = out - B;
+ if (len <= B || len > 2 * B)
+ abort ();
+ printf ("(did CBC mode for %d)\n", len2);
+
+ D(in);
+ xor (pn1, in, iv);
+ D(pn1);
+ r = camellia_enc_blk (pn1, cn, &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ D(cn);
+ memset (pn, 0, sizeof(pn));
+ memcpy (pn, in+B, len-B);
+ D(pn);
+ xor (pn, pn, cn);
+ D(pn);
+ r = camellia_enc_blk (pn, cn1, &ctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ D(cn1);
+ memcpy(out, cn1, B);
+ memcpy(out+B, cn, len-B);
+}
+
+static void
+cts_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
+ unsigned int len)
+{
+ int r;
+ unsigned int len2;
+ unsigned char pn1[B], pn[B], cn[B], cn1[B];
+
+ if (len < B + 1) abort ();
+ len2 = (len - B - 1) & ~(B-1);
+ cbc_dec (out, in, iv, len2);
+ out += len2;
+ in += len2;
+ len -= len2;
+ if (len2)
+ iv = in - B;
+ if (len <= B || len > 2 * B)
+ abort ();
+
+ memcpy (cn1, in, B);
+ r = camellia_dec_blk (cn1, pn, &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ memset (cn, 0, sizeof(cn));
+ memcpy (cn, in+B, len-B);
+ xor (pn, pn, cn);
+ memcpy (cn+len-B, pn+len-B, 2*B-len);
+ r = camellia_dec_blk (cn, pn1, &dctx);
+ if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+ xor (pn1, pn1, iv);
+ memcpy(out, pn1, B);
+ memcpy(out+B, pn, len-B);
+}
+
+static void ecb_test ()
+{
+ size_t testno;
+ unsigned char tmp[4*B];
+
+ printf ("ECB tests:\n");
+ printf ("key:");
+ hexdump (key, sizeof(key));
+ for (testno = 0; testno < NTESTS; testno++) {
+ unsigned len = (test_case_len[testno] + 15) & ~15;
+ printf ("\ntest %d - %d bytes\n", (int)testno, len);
+ printf ("input:");
+ hexdump (test_case[testno].input, len);
+ printf ("\n");
+ ecb_enc (test_case[testno].output, test_case[testno].input, len);
+ printf ("output:");
+ hexdump (test_case[testno].output, len);
+ printf ("\n");
+ ecb_dec (tmp, test_case[testno].output, len);
+ if (memcmp (tmp, test_case[testno].input, len)) {
+ printf ("ecb decrypt failed!!");
+ hexdump (tmp, len);
+ printf ("\n");
+ exit (1);
+ }
+ }
+ printf ("\n");
+}
+
+unsigned char ivec[16] = { 0 };
+
+static void cbc_test ()
+{
+ size_t testno;
+ unsigned char tmp[4*B];
+
+ printf ("CBC tests:\n");
+ printf ("initial vector:");
+ hexdump (ivec, sizeof(ivec));
+ for (testno = 0; testno < NTESTS; testno++) {
+ unsigned len = (test_case_len[testno] + 15) & ~15;
+ printf ("\ntest %d - %d bytes\n", (int)testno, len);
+ printf ("input:");
+ hexdump (test_case[testno].input, len);
+ printf ("\n");
+ cbc_enc (test_case[testno].output, test_case[testno].input, ivec, len);
+ printf ("output:");
+ hexdump (test_case[testno].output, len);
+ printf ("\n");
+ cbc_dec (tmp, test_case[testno].output, ivec, len);
+ if (memcmp (tmp, test_case[testno].input, len)) {
+ printf("cbc decrypt failed!!");
+ hexdump (tmp, len);
+ printf ("\n");
+ exit(1);
+ }
+ }
+ printf ("\n");
+}
+
+static void cts_test ()
+{
+ size_t testno;
+ unsigned char tmp[4*B];
+
+ printf ("CTS tests:\n");
+ printf ("initial vector:");
+ hexdump (ivec, sizeof(ivec));
+ for (testno = 0; testno < NTESTS; testno++) {
+ unsigned int len = test_case_len[testno];
+ printf ("\ntest %d - %d bytes\n", (int)testno, len);
+ printf ("input:");
+ hexdump (test_case[testno].input, len);
+ printf ("\n");
+ cts_enc (test_case[testno].output, test_case[testno].input, ivec, len);
+ printf ("output:");
+ hexdump (test_case[testno].output, len);
+ printf ("\n");
+ cts_dec (tmp, test_case[testno].output, ivec, len);
+ if (memcmp (tmp, test_case[testno].input, len))
+ fprintf (stderr, "cts decrypt failed!!\n"), exit(1);
+ }
+ printf ("\n");
+}
+
+int main ()
+{
+ init ();
+ fips_test ();
+
+ ecb_test();
+ cbc_test();
+ cts_test();
+
+ return 0;
+}
+
diff --git a/src/lib/crypto/builtin/camellia/camellia.c b/src/lib/crypto/builtin/camellia/camellia.c
new file mode 100644
index 000000000000..88dfe99ad9ad
--- /dev/null
+++ b/src/lib/crypto/builtin/camellia/camellia.c
@@ -0,0 +1,1539 @@
+/* lib/crypto/builtin/camellia/camellia.c - Camellia version 1.2.0 */
+/*
+ * Copyright (c) 2006,2007,2009
+ * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "camellia.h"
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L (0xA09E667FL)
+#define CAMELLIA_SIGMA1R (0x3BCC908BL)
+#define CAMELLIA_SIGMA2L (0xB67AE858L)
+#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L (0xC6EF372FL)
+#define CAMELLIA_SIGMA3R (0xE94F82BEL)
+#define CAMELLIA_SIGMA4L (0x54FF53A5L)
+#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L (0x10E527FAL)
+#define CAMELLIA_SIGMA5R (0xDE682D1DL)
+#define CAMELLIA_SIGMA6L (0xB05688C2L)
+#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
+
+/*
+ * macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt) \
+ (((u32)(pt)[0] << 24) \
+ ^ ((u32)(pt)[1] << 16) \
+ ^ ((u32)(pt)[2] << 8) \
+ ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st) { \
+ (ct)[0] = (u8)((st) >> 24); \
+ (ct)[1] = (u8)((st) >> 16); \
+ (ct)[2] = (u8)((st) >> 8); \
+ (ct)[3] = (u8)(st); }
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ ll = (ll << bits) + (lr >> (32 - bits)); \
+ lr = (lr << bits) + (rl >> (32 - bits)); \
+ rl = (rl << bits) + (rr >> (32 - bits)); \
+ rr = (rr << bits) + (w0 >> (32 - bits)); \
+ } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ w1 = lr; \
+ ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
+ lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
+ rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
+ rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
+ } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ il = xl ^ kl; \
+ ir = xr ^ kr; \
+ t0 = il >> 16; \
+ t1 = ir >> 16; \
+ yl = CAMELLIA_SP1110(ir & 0xff) \
+ ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \
+ ^ CAMELLIA_SP3033(t1 & 0xff) \
+ ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \
+ yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \
+ ^ CAMELLIA_SP0222(t0 & 0xff) \
+ ^ CAMELLIA_SP3033((il >> 8) & 0xff) \
+ ^ CAMELLIA_SP4404(il & 0xff); \
+ yl ^= yr; \
+ yr = CAMELLIA_RR8(yr); \
+ yr ^= yl; \
+ } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+ do { \
+ t0 = kll; \
+ t0 &= ll; \
+ lr ^= CAMELLIA_RL1(t0); \
+ t1 = klr; \
+ t1 |= lr; \
+ ll ^= t1; \
+ \
+ t2 = krr; \
+ t2 |= rr; \
+ rl ^= t2; \
+ t3 = krl; \
+ t3 &= rl; \
+ rr ^= CAMELLIA_RL1(t3); \
+ } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ ir = CAMELLIA_SP1110(xr & 0xff) \
+ ^ CAMELLIA_SP0222((xr >> 24) & 0xff) \
+ ^ CAMELLIA_SP3033((xr >> 16) & 0xff) \
+ ^ CAMELLIA_SP4404((xr >> 8) & 0xff); \
+ il = CAMELLIA_SP1110((xl >> 24) & 0xff) \
+ ^ CAMELLIA_SP0222((xl >> 16) & 0xff) \
+ ^ CAMELLIA_SP3033((xl >> 8) & 0xff) \
+ ^ CAMELLIA_SP4404(xl & 0xff); \
+ il ^= kl; \
+ ir ^= kr; \
+ ir ^= il; \
+ il = CAMELLIA_RR8(il); \
+ il ^= ir; \
+ yl ^= ir; \
+ yr ^= il; \
+ } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+ 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+ 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+ 0xe4e4e400,0x85858500,0x57575700,0x35353500,
+ 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+ 0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+ 0x45454500,0x19191900,0xa5a5a500,0x21212100,
+ 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+ 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+ 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+ 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+ 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+ 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+ 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+ 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+ 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+ 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+ 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+ 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+ 0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+ 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+ 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+ 0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+ 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+ 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+ 0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+ 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+ 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+ 0x53535300,0x18181800,0xf2f2f200,0x22222200,
+ 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+ 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+ 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+ 0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+ 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+ 0xa1a1a100,0x89898900,0x62626200,0x97979700,
+ 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+ 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+ 0x10101000,0xc4c4c400,0x00000000,0x48484800,
+ 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+ 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+ 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+ 0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+ 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+ 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+ 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+ 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+ 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+ 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+ 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+ 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+ 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+ 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+ 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+ 0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+ 0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+ 0xd4d4d400,0x25252500,0xababab00,0x42424200,
+ 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+ 0x72727200,0x07070700,0xb9b9b900,0x55555500,
+ 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+ 0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+ 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+ 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+ 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+ 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+ 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+ 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+ 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+ 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+ 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+ 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+ 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+ 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+ 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+ 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+ 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+ 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+ 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+ 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+ 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+ 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+ 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+ 0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+ 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+ 0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+ 0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+ 0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+ 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+ 0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+ 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+ 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+ 0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+ 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+ 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+ 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+ 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+ 0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+ 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+ 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+ 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+ 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+ 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+ 0x00202020,0x00898989,0x00000000,0x00909090,
+ 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+ 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+ 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+ 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+ 0x009b9b9b,0x00949494,0x00212121,0x00666666,
+ 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+ 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+ 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+ 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+ 0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+ 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+ 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+ 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+ 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+ 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+ 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+ 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+ 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+ 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+ 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+ 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+ 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+ 0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+ 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+ 0x00777777,0x00939393,0x00868686,0x00838383,
+ 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+ 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+ 0x38003838,0x41004141,0x16001616,0x76007676,
+ 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+ 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+ 0x75007575,0x06000606,0x57005757,0xa000a0a0,
+ 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+ 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+ 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+ 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+ 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+ 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+ 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+ 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+ 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+ 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+ 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+ 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+ 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+ 0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+ 0x3a003a3a,0x09000909,0x95009595,0x10001010,
+ 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+ 0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+ 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+ 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+ 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+ 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+ 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+ 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+ 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+ 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+ 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+ 0x12001212,0x04000404,0x74007474,0x54005454,
+ 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+ 0x55005555,0x68006868,0x50005050,0xbe00bebe,
+ 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+ 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+ 0x70007070,0xff00ffff,0x32003232,0x69006969,
+ 0x08000808,0x62006262,0x00000000,0x24002424,
+ 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+ 0x45004545,0x81008181,0x73007373,0x6d006d6d,
+ 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+ 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+ 0xe600e6e6,0x25002525,0x48004848,0x99009999,
+ 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+ 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+ 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+ 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+ 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+ 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+ 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+ 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+ 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+ 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+ 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+ 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+ 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+ 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+ 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+ 0x7c007c7c,0x77007777,0x56005656,0x05000505,
+ 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+ 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+ 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+ 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+ 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+ 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+ 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+ 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+ 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+ 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+ 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+ 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+ 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+ 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+ 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+ 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+ 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+ 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+ 0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+ 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+ 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+ 0x24240024,0xe8e800e8,0x60600060,0x69690069,
+ 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+ 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+ 0x10100010,0x00000000,0xa3a300a3,0x75750075,
+ 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+ 0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+ 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+ 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+ 0x81810081,0x6f6f006f,0x13130013,0x63630063,
+ 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+ 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+ 0x78780078,0x06060006,0xe7e700e7,0x71710071,
+ 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+ 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+ 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+ 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+ 0x15150015,0xadad00ad,0x77770077,0x80800080,
+ 0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+ 0x85850085,0x35350035,0x0c0c000c,0x41410041,
+ 0xefef00ef,0x93930093,0x19190019,0x21210021,
+ 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+ 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+ 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+ 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+ 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+ 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+ 0x12120012,0x20200020,0xb1b100b1,0x99990099,
+ 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+ 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+ 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+ 0x0f0f000f,0x16160016,0x18180018,0x22220022,
+ 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+ 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+ 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+ 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+ 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+ 0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+ 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+ 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+ 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+ 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+ 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+ 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+ 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+ 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+ 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+ 0x49490049,0x68680068,0x38380038,0xa4a400a4,
+ 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+ 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+void
+camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+ u32 kll, klr, krl, krr;
+ u32 il, ir, t0, t1, w0, w1;
+ u32 kw4l, kw4r, dw, tl, tr;
+ u32 subL[26];
+ u32 subR[26];
+
+ /**
+ * k == kll || klr || krl || krr (|| is concatination)
+ */
+ kll = GETU32(key );
+ klr = GETU32(key + 4);
+ krl = GETU32(key + 8);
+ krr = GETU32(key + 12);
+ /**
+ * generate KL dependent subkeys
+ */
+ subl(0) = kll; subr(0) = klr;
+ subl(1) = krl; subr(1) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(4) = kll; subr(4) = klr;
+ subl(5) = krl; subr(5) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subl(10) = kll; subr(10) = klr;
+ subl(11) = krl; subr(11) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(13) = krl; subr(13) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(16) = kll; subr(16) = klr;
+ subl(17) = krl; subr(17) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(18) = kll; subr(18) = klr;
+ subl(19) = krl; subr(19) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(22) = kll; subr(22) = klr;
+ subl(23) = krl; subr(23) = krr;
+
+ /* generate KA */
+ kll = subl(0); klr = subr(0);
+ krl = subl(1); krr = subr(1);
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+ w0, w1, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+ kll, klr, il, ir, t0, t1);
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+ krl, krr, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0; klr ^= w1;
+
+ /* generate KA dependent subkeys */
+ subl(2) = kll; subr(2) = klr;
+ subl(3) = krl; subr(3) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(6) = kll; subr(6) = klr;
+ subl(7) = krl; subr(7) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(8) = kll; subr(8) = klr;
+ subl(9) = krl; subr(9) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(12) = kll; subr(12) = klr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(14) = kll; subr(14) = klr;
+ subl(15) = krl; subr(15) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subl(20) = kll; subr(20) = klr;
+ subl(21) = krl; subr(21) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(24) = kll; subr(24) = klr;
+ subl(25) = krl; subr(25) = krr;
+
+
+ /* absorb kw2 to other subkeys */
+ subl(3) ^= subl(1); subr(3) ^= subr(1);
+ subl(5) ^= subl(1); subr(5) ^= subr(1);
+ subl(7) ^= subl(1); subr(7) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(9);
+ dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(11) ^= subl(1); subr(11) ^= subr(1);
+ subl(13) ^= subl(1); subr(13) ^= subr(1);
+ subl(15) ^= subl(1); subr(15) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(17);
+ dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(19) ^= subl(1); subr(19) ^= subr(1);
+ subl(21) ^= subl(1); subr(21) ^= subr(1);
+ subl(23) ^= subl(1); subr(23) ^= subr(1);
+ subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subl(25); kw4r = subr(25);
+ subl(22) ^= kw4l; subr(22) ^= kw4r;
+ subl(20) ^= kw4l; subr(20) ^= kw4r;
+ subl(18) ^= kw4l; subr(18) ^= kw4r;
+ kw4l ^= kw4r & ~subr(16);
+ dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+ subl(14) ^= kw4l; subr(14) ^= kw4r;
+ subl(12) ^= kw4l; subr(12) ^= kw4r;
+ subl(10) ^= kw4l; subr(10) ^= kw4r;
+ kw4l ^= kw4r & ~subr(8);
+ dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+ subl(6) ^= kw4l; subr(6) ^= kw4r;
+ subl(4) ^= kw4l; subr(4) ^= kw4r;
+ subl(2) ^= kw4l; subr(2) ^= kw4r;
+ subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+ /* key XOR is end of F-function */
+ CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+ CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+ CamelliaSubkeyL(2) = subl(3);
+ CamelliaSubkeyR(2) = subr(3);
+ CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+ CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+ CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+ CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+ CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+ CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+ CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+ CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+ tl = subl(10) ^ (subr(10) & ~subr(8));
+ dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(7) = subl(6) ^ tl;
+ CamelliaSubkeyR(7) = subr(6) ^ tr;
+ CamelliaSubkeyL(8) = subl(8);
+ CamelliaSubkeyR(8) = subr(8);
+ CamelliaSubkeyL(9) = subl(9);
+ CamelliaSubkeyR(9) = subr(9);
+ tl = subl(7) ^ (subr(7) & ~subr(9));
+ dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(10) = tl ^ subl(11);
+ CamelliaSubkeyR(10) = tr ^ subr(11);
+ CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+ CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+ CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+ CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+ CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+ CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+ CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+ CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+ tl = subl(18) ^ (subr(18) & ~subr(16));
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(15) = subl(14) ^ tl;
+ CamelliaSubkeyR(15) = subr(14) ^ tr;
+ CamelliaSubkeyL(16) = subl(16);
+ CamelliaSubkeyR(16) = subr(16);
+ CamelliaSubkeyL(17) = subl(17);
+ CamelliaSubkeyR(17) = subr(17);
+ tl = subl(15) ^ (subr(15) & ~subr(17));
+ dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(18) = tl ^ subl(19);
+ CamelliaSubkeyR(18) = tr ^ subr(19);
+ CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+ CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+ CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+ CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+ CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+ CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+ CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+ CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+ CamelliaSubkeyL(23) = subl(22);
+ CamelliaSubkeyR(23) = subr(22);
+ CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+ CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+ /* apply the inverse of the last half of P-function */
+ dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+ dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+ dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+ dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+ dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+ dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+ dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+ dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+ dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+ dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+ dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+ dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+ dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+ dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+ dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+ dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+ dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+ dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+
+ return;
+}
+
+void
+camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+ u32 kll,klr,krl,krr; /* left half of key */
+ u32 krll,krlr,krrl,krrr; /* right half of key */
+ u32 il, ir, t0, t1, w0, w1; /* temporary variables */
+ u32 kw4l, kw4r, dw, tl, tr;
+ u32 subL[34];
+ u32 subR[34];
+
+ /**
+ * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+ * (|| is concatination)
+ */
+
+ kll = GETU32(key );
+ klr = GETU32(key + 4);
+ krl = GETU32(key + 8);
+ krr = GETU32(key + 12);
+ krll = GETU32(key + 16);
+ krlr = GETU32(key + 20);
+ krrl = GETU32(key + 24);
+ krrr = GETU32(key + 28);
+
+ /* generate KL dependent subkeys */
+ subl(0) = kll; subr(0) = klr;
+ subl(1) = krl; subr(1) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+ subl(12) = kll; subr(12) = klr;
+ subl(13) = krl; subr(13) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(16) = kll; subr(16) = klr;
+ subl(17) = krl; subr(17) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(22) = kll; subr(22) = klr;
+ subl(23) = krl; subr(23) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subl(30) = kll; subr(30) = klr;
+ subl(31) = krl; subr(31) = krr;
+
+ /* generate KR dependent subkeys */
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subl(4) = krll; subr(4) = krlr;
+ subl(5) = krrl; subr(5) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subl(8) = krll; subr(8) = krlr;
+ subl(9) = krrl; subr(9) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(18) = krll; subr(18) = krlr;
+ subl(19) = krrl; subr(19) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+ subl(26) = krll; subr(26) = krlr;
+ subl(27) = krrl; subr(27) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+ /* generate KA */
+ kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+ krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+ w0, w1, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+ kll, klr, il, ir, t0, t1);
+ kll ^= krll; klr ^= krlr;
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+ krl, krr, il, ir, t0, t1);
+ krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0; klr ^= w1;
+
+ /* generate KB */
+ krll ^= kll; krlr ^= klr;
+ krrl ^= krl; krrr ^= krr;
+ CAMELLIA_F(krll, krlr,
+ CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+ w0, w1, il, ir, t0, t1);
+ krrl ^= w0; krrr ^= w1;
+ CAMELLIA_F(krrl, krrr,
+ CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+ w0, w1, il, ir, t0, t1);
+ krll ^= w0; krlr ^= w1;
+
+ /* generate KA dependent subkeys */
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(6) = kll; subr(6) = klr;
+ subl(7) = krl; subr(7) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subl(14) = kll; subr(14) = klr;
+ subl(15) = krl; subr(15) = krr;
+ subl(24) = klr; subr(24) = krl;
+ subl(25) = krr; subr(25) = kll;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+ subl(28) = kll; subr(28) = klr;
+ subl(29) = krl; subr(29) = krr;
+
+ /* generate KB dependent subkeys */
+ subl(2) = krll; subr(2) = krlr;
+ subl(3) = krrl; subr(3) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(10) = krll; subr(10) = krlr;
+ subl(11) = krrl; subr(11) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(20) = krll; subr(20) = krlr;
+ subl(21) = krrl; subr(21) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+ subl(32) = krll; subr(32) = krlr;
+ subl(33) = krrl; subr(33) = krrr;
+
+ /* absorb kw2 to other subkeys */
+ subl(3) ^= subl(1); subr(3) ^= subr(1);
+ subl(5) ^= subl(1); subr(5) ^= subr(1);
+ subl(7) ^= subl(1); subr(7) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(9);
+ dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(11) ^= subl(1); subr(11) ^= subr(1);
+ subl(13) ^= subl(1); subr(13) ^= subr(1);
+ subl(15) ^= subl(1); subr(15) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(17);
+ dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(19) ^= subl(1); subr(19) ^= subr(1);
+ subl(21) ^= subl(1); subr(21) ^= subr(1);
+ subl(23) ^= subl(1); subr(23) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(25);
+ dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(27) ^= subl(1); subr(27) ^= subr(1);
+ subl(29) ^= subl(1); subr(29) ^= subr(1);
+ subl(31) ^= subl(1); subr(31) ^= subr(1);
+ subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subl(33); kw4r = subr(33);
+ subl(30) ^= kw4l; subr(30) ^= kw4r;
+ subl(28) ^= kw4l; subr(28) ^= kw4r;
+ subl(26) ^= kw4l; subr(26) ^= kw4r;
+ kw4l ^= kw4r & ~subr(24);
+ dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+ subl(22) ^= kw4l; subr(22) ^= kw4r;
+ subl(20) ^= kw4l; subr(20) ^= kw4r;
+ subl(18) ^= kw4l; subr(18) ^= kw4r;
+ kw4l ^= kw4r & ~subr(16);
+ dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+ subl(14) ^= kw4l; subr(14) ^= kw4r;
+ subl(12) ^= kw4l; subr(12) ^= kw4r;
+ subl(10) ^= kw4l; subr(10) ^= kw4r;
+ kw4l ^= kw4r & ~subr(8);
+ dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+ subl(6) ^= kw4l; subr(6) ^= kw4r;
+ subl(4) ^= kw4l; subr(4) ^= kw4r;
+ subl(2) ^= kw4l; subr(2) ^= kw4r;
+ subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+ /* key XOR is end of F-function */
+ CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+ CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+ CamelliaSubkeyL(2) = subl(3);
+ CamelliaSubkeyR(2) = subr(3);
+ CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+ CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+ CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+ CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+ CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+ CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+ CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+ CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+ tl = subl(10) ^ (subr(10) & ~subr(8));
+ dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(7) = subl(6) ^ tl;
+ CamelliaSubkeyR(7) = subr(6) ^ tr;
+ CamelliaSubkeyL(8) = subl(8);
+ CamelliaSubkeyR(8) = subr(8);
+ CamelliaSubkeyL(9) = subl(9);
+ CamelliaSubkeyR(9) = subr(9);
+ tl = subl(7) ^ (subr(7) & ~subr(9));
+ dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(10) = tl ^ subl(11);
+ CamelliaSubkeyR(10) = tr ^ subr(11);
+ CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+ CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+ CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+ CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+ CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+ CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+ CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+ CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+ tl = subl(18) ^ (subr(18) & ~subr(16));
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(15) = subl(14) ^ tl;
+ CamelliaSubkeyR(15) = subr(14) ^ tr;
+ CamelliaSubkeyL(16) = subl(16);
+ CamelliaSubkeyR(16) = subr(16);
+ CamelliaSubkeyL(17) = subl(17);
+ CamelliaSubkeyR(17) = subr(17);
+ tl = subl(15) ^ (subr(15) & ~subr(17));
+ dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(18) = tl ^ subl(19);
+ CamelliaSubkeyR(18) = tr ^ subr(19);
+ CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+ CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+ CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+ CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+ CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+ CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+ CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+ CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+ tl = subl(26) ^ (subr(26) & ~subr(24));
+ dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(23) = subl(22) ^ tl;
+ CamelliaSubkeyR(23) = subr(22) ^ tr;
+ CamelliaSubkeyL(24) = subl(24);
+ CamelliaSubkeyR(24) = subr(24);
+ CamelliaSubkeyL(25) = subl(25);
+ CamelliaSubkeyR(25) = subr(25);
+ tl = subl(23) ^ (subr(23) & ~subr(25));
+ dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(26) = tl ^ subl(27);
+ CamelliaSubkeyR(26) = tr ^ subr(27);
+ CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+ CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+ CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+ CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+ CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+ CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+ CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+ CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+ CamelliaSubkeyL(31) = subl(30);
+ CamelliaSubkeyR(31) = subr(30);
+ CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+ CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+ /* apply the inverse of the last half of P-function */
+ dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+ dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+ dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+ dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+ dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+ dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+ dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+ dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+ dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+ dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+ dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+ dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+ dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+ dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+ dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+ dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+ dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+ dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+ dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
+ dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
+ dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
+ dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
+ dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
+ dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
+
+ return;
+}
+
+void
+camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+ unsigned char kk[32];
+ u32 krll, krlr, krrl,krrr;
+
+ memcpy(kk, key, 24);
+ memcpy((unsigned char *)&krll, key+16,4);
+ memcpy((unsigned char *)&krlr, key+20,4);
+ krrl = ~krll;
+ krrr = ~krlr;
+ memcpy(kk+24, (unsigned char *)&krrl, 4);
+ memcpy(kk+28, (unsigned char *)&krrr, 4);
+ camellia_setup256(kk, subkey);
+ return;
+}
+
+
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+void
+camellia_encrypt128(const u32 *subkey, u32 *io)
+{
+ u32 il, ir, t0, t1;
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(0);
+ io[1] ^= CamelliaSubkeyR(0);
+ /* main iteration */
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(24);
+ io[3] ^= CamelliaSubkeyR(24);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+void
+camellia_decrypt128(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(24);
+ io[1] ^= CamelliaSubkeyR(24);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(0);
+ io[3] ^= CamelliaSubkeyR(0);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+void
+camellia_encrypt256(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(0);
+ io[1] ^= CamelliaSubkeyR(0);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+ CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(32);
+ io[3] ^= CamelliaSubkeyR(32);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+void
+camellia_decrypt256(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(32);
+ io[1] ^= CamelliaSubkeyR(32);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+ CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(0);
+ io[3] ^= CamelliaSubkeyR(0);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+/***
+ *
+ * API for compatibility
+ */
+
+void
+Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
+ KEY_TABLE_TYPE keyTable)
+{
+ switch(keyBitLength) {
+ case 128:
+ camellia_setup128(rawKey, keyTable);
+ break;
+ case 192:
+ camellia_setup192(rawKey, keyTable);
+ break;
+ case 256:
+ camellia_setup256(rawKey, keyTable);
+ break;
+ default:
+ break;
+ }
+}
+
+
+void
+Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *ciphertext)
+{
+ u32 tmp[4];
+
+ tmp[0] = GETU32(plaintext);
+ tmp[1] = GETU32(plaintext + 4);
+ tmp[2] = GETU32(plaintext + 8);
+ tmp[3] = GETU32(plaintext + 12);
+
+ switch (keyBitLength) {
+ case 128:
+ camellia_encrypt128(keyTable, tmp);
+ break;
+ case 192:
+ /* fall through */
+ case 256:
+ camellia_encrypt256(keyTable, tmp);
+ break;
+ default:
+ break;
+ }
+
+ PUTU32(ciphertext, tmp[0]);
+ PUTU32(ciphertext + 4, tmp[1]);
+ PUTU32(ciphertext + 8, tmp[2]);
+ PUTU32(ciphertext + 12, tmp[3]);
+}
+
+void
+Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *ciphertext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *plaintext)
+{
+ u32 tmp[4];
+
+ tmp[0] = GETU32(ciphertext);
+ tmp[1] = GETU32(ciphertext + 4);
+ tmp[2] = GETU32(ciphertext + 8);
+ tmp[3] = GETU32(ciphertext + 12);
+
+ switch (keyBitLength) {
+ case 128:
+ camellia_decrypt128(keyTable, tmp);
+ break;
+ case 192:
+ /* fall through */
+ case 256:
+ camellia_decrypt256(keyTable, tmp);
+ break;
+ default:
+ break;
+ }
+ PUTU32(plaintext, tmp[0]);
+ PUTU32(plaintext + 4, tmp[1]);
+ PUTU32(plaintext + 8, tmp[2]);
+ PUTU32(plaintext + 12, tmp[3]);
+}
+
+cam_rval
+camellia_blk_len(unsigned int blen, camellia_ctx cx[1]){
+ if(blen != 16) return camellia_bad;
+ return camellia_good;
+}
+
+cam_rval
+camellia_enc_key(const unsigned char in_key[], unsigned int klen,
+ camellia_ctx cx[1]){
+ switch(klen){
+ case 16:
+ camellia_setup128(in_key, cx->k_sch);
+ cx->keybitlen = 128;
+ break;
+ case 24:
+ camellia_setup192(in_key, cx->k_sch);
+ cx->keybitlen = 192;
+ break;
+ case 32:
+ camellia_setup256(in_key, cx->k_sch);
+ cx->keybitlen = 256;
+ break;
+ default:
+ return camellia_bad;
+ }
+ return camellia_good;
+}
+
+cam_rval
+camellia_enc_blk(const unsigned char in_blk[], unsigned char out_blk[],
+ const camellia_ctx cx[1]){
+ Camellia_EncryptBlock(cx->keybitlen, in_blk, cx->k_sch, out_blk);
+ return camellia_good;
+}
+
+cam_rval
+camellia_dec_key(const unsigned char in_key[], unsigned int klen,
+ camellia_ctx cx[1]){
+ switch(klen){
+ case 16:
+ camellia_setup128(in_key, cx->k_sch);
+ cx->keybitlen = 128;
+ break;
+ case 24:
+ camellia_setup192(in_key, cx->k_sch);
+ cx->keybitlen = 192;
+ break;
+ case 32:
+ camellia_setup256(in_key, cx->k_sch);
+ cx->keybitlen = 256;
+ break;
+ default:
+ return camellia_bad;
+ }
+ return camellia_good;
+}
+
+cam_rval
+camellia_dec_blk(const unsigned char in_blk[], unsigned char out_blk[],
+ const camellia_ctx cx[1]){
+ Camellia_DecryptBlock(cx->keybitlen, in_blk, cx->k_sch, out_blk);
+ return camellia_good;
+}
diff --git a/src/lib/crypto/builtin/camellia/camellia.h b/src/lib/crypto/builtin/camellia/camellia.h
new file mode 100644
index 000000000000..571ba68a669b
--- /dev/null
+++ b/src/lib/crypto/builtin/camellia/camellia.h
@@ -0,0 +1,125 @@
+/* lib/crypto/builtin/camellia/camellia.h - Camellia version 1.2.0 */
+/*
+ * Copyright (c) 2006,2007,2009
+ * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+#ifndef BLOCK_SIZE
+#define BLOCK_SIZE CAMELLIA_BLOCK_SIZE
+#endif
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+
+/* u32 must be 32bit word */
+typedef uint32_t u32;
+typedef uint8_t u8;
+
+/* For the Kerberos 5 tree, hide the Camellia symbol names. */
+#define camellia_setup128 k5_camellia_setup128
+#define camellia_setup192 k5_camellia_setup192
+#define camellia_setup256 k5_camellia_setup256
+#define camellia_encrypt128 k5_camellia_encrypt128
+#define camellia_decrypt128 k5_camellia_decrypt128
+#define camellia_encrypt256 k5_camellia_encrypt256
+#define camellia_decrypt256 k5_camellia_decrypt256
+#define Camellia_Ekeygen k5_Camellia_Ekeygen
+#define Camellia_EncryptBlock k5_Camellia_EncryptBlock
+#define Camellia_DecryptBlock k5_Camellia_DecryptBlock
+
+void camellia_setup128(const unsigned char *key, u32 *subkey);
+void camellia_setup192(const unsigned char *key, u32 *subkey);
+void camellia_setup256(const unsigned char *key, u32 *subkey);
+void camellia_encrypt128(const u32 *subkey, u32 *io);
+void camellia_decrypt128(const u32 *subkey, u32 *io);
+void camellia_encrypt256(const u32 *subkey, u32 *io);
+void camellia_decrypt256(const u32 *subkey, u32 *io);
+
+void Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
+ KEY_TABLE_TYPE keyTable);
+
+void Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *cipherText);
+
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *cipherText,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *plaintext);
+
+
+typedef uint16_t cam_fret; /* type for function return value */
+#define camellia_good 1
+#define camellia_bad 1
+#ifndef CAMELLIA_DLL /* implement normal or DLL functions */
+#define cam_rval cam_fret
+#else
+#define cam_rval cam_fret __declspec(dllexport) _stdcall
+#endif
+
+typedef struct /* the Camellia context for encryption */
+{
+ uint32_t k_sch[CAMELLIA_TABLE_WORD_LEN]; /* the encryption key schedule */
+ int keybitlen; /* bitlength of key */
+} camellia_ctx;
+
+
+/* for Kerberos 5 tree -- hide names! */
+#define camellia_blk_len krb5int_camellia_blk_len
+#define camellia_enc_key krb5int_camellia_enc_key
+#define camellia_enc_blk krb5int_camellia_enc_blk
+#define camellia_dec_key krb5int_camellia_dec_key
+#define camellia_dec_blk krb5int_camellia_dec_blk
+
+cam_rval camellia_blk_len(unsigned int blen, camellia_ctx cx[1]);
+cam_rval camellia_enc_key(const unsigned char in_key[], unsigned int klen,
+ camellia_ctx cx[1]);
+cam_rval camellia_enc_blk(const unsigned char in_blk[],
+ unsigned char out_blk[],
+ const camellia_ctx cx[1]);
+cam_rval camellia_dec_key(const unsigned char in_key[], unsigned int klen,
+ camellia_ctx cx[1]);
+cam_rval camellia_dec_blk(const unsigned char in_blk[],
+ unsigned char out_blk[],
+ const camellia_ctx cx[1]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_CAMELLIA_H */
diff --git a/src/lib/crypto/builtin/camellia/deps b/src/lib/crypto/builtin/camellia/deps
new file mode 100644
index 000000000000..ff62c7274039
--- /dev/null
+++ b/src/lib/crypto/builtin/camellia/deps
@@ -0,0 +1,5 @@
+#
+# Generated makefile dependencies follow.
+#
+camellia.so camellia.po $(OUTPRE)camellia.$(OBJEXT): \
+ camellia.c camellia.h
diff --git a/src/lib/crypto/builtin/crypto_mod.h b/src/lib/crypto/builtin/crypto_mod.h
new file mode 100644
index 000000000000..f85e32215572
--- /dev/null
+++ b/src/lib/crypto/builtin/crypto_mod.h
@@ -0,0 +1,39 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/crypto_mod.h - Builtin crypto module declarations */
+/*
+ * Copyright (C) 2011 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * This header is included from lib/crypto/krb/crypto_int.h to provide
+ * module-specific declarations. It is not included directly from source
+ * files.
+ */
+
+#ifndef CRYPTO_MOD_H
+#define CRYPTO_MOD_H
+
+#include <aes/aes.h>
+#include <sha2/sha2.h>
+
+#endif /* CRYPTO_MOD_H */
diff --git a/src/lib/crypto/builtin/deps b/src/lib/crypto/builtin/deps
new file mode 100644
index 000000000000..54e242ef1f16
--- /dev/null
+++ b/src/lib/crypto/builtin/deps
@@ -0,0 +1,36 @@
+#
+# Generated makefile dependencies follow.
+#
+hmac.so hmac.po $(OUTPRE)hmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \
+ $(srcdir)/aes/aes.h $(srcdir)/sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h crypto_mod.h hmac.c
+init.so init.po $(OUTPRE)init.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \
+ $(srcdir)/aes/aes.h $(srcdir)/sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h crypto_mod.h init.c
+pbkdf2.so pbkdf2.po $(OUTPRE)pbkdf2.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \
+ $(srcdir)/aes/aes.h $(srcdir)/sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h crypto_mod.h pbkdf2.c
diff --git a/src/lib/crypto/builtin/des/ISSUES b/src/lib/crypto/builtin/des/ISSUES
new file mode 100644
index 000000000000..157891103345
--- /dev/null
+++ b/src/lib/crypto/builtin/des/ISSUES
@@ -0,0 +1,13 @@
+Issues to be addressed for src/lib/crypto/des: -*- text -*-
+
+
+"const" could be used in more places
+
+
+Array types are used in calling interfaces. Under ANSI C, a value of
+type "arraytype *" cannot be assigned to a variable of type "const
+arraytype *", so we get compilation warnings.
+
+Possible fix: Rewrite internal interfaces to not use arrays this way.
+Provide external routines compatible with old API, but not using
+const?
diff --git a/src/lib/crypto/builtin/des/Makefile.in b/src/lib/crypto/builtin/des/Makefile.in
new file mode 100644
index 000000000000..ed25dab7c8c8
--- /dev/null
+++ b/src/lib/crypto/builtin/des/Makefile.in
@@ -0,0 +1,80 @@
+mydir=lib$(S)crypto$(S)builtin$(S)des
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../krb
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR = builtin\des
+##DOS##OBJFILE = ..\..\$(OUTPRE)des.lst
+
+STLIBOBJS=\
+ d3_aead.o \
+ d3_kysched.o \
+ des_keys.o \
+ f_aead.o \
+ f_cksum.o \
+ f_parity.o \
+ f_sched.o \
+ f_tables.o \
+ key_sched.o \
+ weak_key.o
+
+OBJS= $(OUTPRE)d3_aead.$(OBJEXT) \
+ $(OUTPRE)d3_kysched.$(OBJEXT) \
+ $(OUTPRE)des_keys.$(OBJEXT) \
+ $(OUTPRE)f_aead.$(OBJEXT) \
+ $(OUTPRE)f_cksum.$(OBJEXT) \
+ $(OUTPRE)f_parity.$(OBJEXT) \
+ $(OUTPRE)f_sched.$(OBJEXT) \
+ $(OUTPRE)f_tables.$(OBJEXT) \
+ $(OUTPRE)key_sched.$(OBJEXT) \
+ $(OUTPRE)weak_key.$(OBJEXT)
+
+SRCS= $(srcdir)/d3_aead.c \
+ $(srcdir)/d3_kysched.c \
+ $(srcdir)/des_keys.c \
+ $(srcdir)/f_aead.c \
+ $(srcdir)/f_cksum.c \
+ $(srcdir)/f_parity.c \
+ $(srcdir)/f_sched.c \
+ $(srcdir)/f_tables.c \
+ $(srcdir)/key_sched.c \
+ $(srcdir)/weak_key.c
+
+EXTRADEPSRCS = $(srcdir)/destest.c $(srcdir)/f_cbc.c $(srcdir)/t_verify.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+TOBJS = $(OUTPRE)key_sched.$(OBJEXT) $(OUTPRE)f_sched.$(OBJEXT) \
+ $(OUTPRE)f_cbc.$(OBJEXT) $(OUTPRE)f_tables.$(OBJEXT) \
+ $(OUTPRE)f_cksum.$(OBJEXT)
+
+verify$(EXEEXT): t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \
+ $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB)
+ $(CC_LINK) -o $@ t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \
+ -lcom_err $(SUPPORT_LIB)
+
+destest$(EXEEXT): destest.$(OBJEXT) $(TOBJS) $(SUPPORT_DEPLIB)
+ $(CC_LINK) -o $@ destest.$(OBJEXT) $(TOBJS) $(SUPPORT_LIB)
+
+all-unix: all-libobjs
+
+check-unix: verify destest
+ $(RUN_TEST) ./verify -z
+ $(RUN_TEST) ./verify -m
+ $(RUN_TEST) ./verify
+ $(RUN_TEST) ./destest < $(srcdir)/keytest.data
+
+includes: depend
+
+depend: $(SRCS)
+
+check-windows:
+
+clean:
+ $(RM) destest.$(OBJEXT) destest$(EXEEXT) verify$(EXEEXT) \
+ t_verify.$(OBJEXT) $(TOBJS)
+
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/des/d3_aead.c b/src/lib/crypto/builtin/des/d3_aead.c
new file mode 100644
index 000000000000..bddf75a474e8
--- /dev/null
+++ b/src/lib/crypto/builtin/des/d3_aead.c
@@ -0,0 +1,133 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2008 by the Massachusetts Institute of Technology.
+ * Copyright 1995 by Richard P. Basch. All Rights Reserved.
+ * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Richard P. Basch,
+ * Lehman Brothers and M.I.T. make no representations about the suitability
+ * of this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include "crypto_int.h"
+#include "des_int.h"
+#include "f_tables.h"
+
+void
+krb5int_des3_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule ks1,
+ const mit_des_key_schedule ks2,
+ const mit_des_key_schedule ks3,
+ mit_des_cblock ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp1, *kp2, *kp3;
+ const unsigned char *ip;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
+
+ /* Get key pointers here. These won't need to be reinitialized. */
+ kp1 = (const unsigned DES_INT32 *)ks1;
+ kp2 = (const unsigned DES_INT32 *)ks2;
+ kp3 = (const unsigned DES_INT32 *)ks3;
+
+ /* Initialize left and right with the contents of the initial vector. */
+ ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+ left = load_32_be(ip);
+ right = load_32_be(ip + 4);
+
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* xor this block with the previous ciphertext. */
+ left ^= load_32_be(block);
+ right ^= load_32_be(block + 4);
+
+ /* Encrypt what we have and store it back into block. */
+ DES_DO_ENCRYPT(left, right, kp1);
+ DES_DO_DECRYPT(left, right, kp2);
+ DES_DO_ENCRYPT(left, right, kp3);
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
+
+ k5_iov_cursor_put(&cursor, block);
+ }
+
+ if (ivec != NULL) {
+ store_32_be(left, ivec);
+ store_32_be(right, ivec + 4);
+ }
+}
+
+void
+krb5int_des3_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule ks1,
+ const mit_des_key_schedule ks2,
+ const mit_des_key_schedule ks3,
+ mit_des_cblock ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp1, *kp2, *kp3;
+ const unsigned char *ip;
+ unsigned DES_INT32 ocipherl, ocipherr;
+ unsigned DES_INT32 cipherl, cipherr;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
+
+ /* Get key pointers here. These won't need to be reinitialized. */
+ kp1 = (const unsigned DES_INT32 *)ks1;
+ kp2 = (const unsigned DES_INT32 *)ks2;
+ kp3 = (const unsigned DES_INT32 *)ks3;
+
+ /*
+ * Decrypting is harder than encrypting because of
+ * the necessity of remembering a lot more things.
+ * Should think about this a little more...
+ */
+
+ /* Prime the old cipher with ivec.*/
+ ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+ ocipherl = load_32_be(ip);
+ ocipherr = load_32_be(ip + 4);
+
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* Split this block into left and right. */
+ cipherl = left = load_32_be(block);
+ cipherr = right = load_32_be(block + 4);
+
+ /* Decrypt and xor with the old cipher to get plain text. */
+ DES_DO_DECRYPT(left, right, kp3);
+ DES_DO_ENCRYPT(left, right, kp2);
+ DES_DO_DECRYPT(left, right, kp1);
+ left ^= ocipherl;
+ right ^= ocipherr;
+
+ /* Store the encrypted halves back into block. */
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
+
+ /* Save current cipher block halves. */
+ ocipherl = cipherl;
+ ocipherr = cipherr;
+
+ k5_iov_cursor_put(&cursor, block);
+ }
+
+ if (ivec != NULL) {
+ store_32_be(ocipherl, ivec);
+ store_32_be(ocipherr, ivec + 4);
+ }
+}
diff --git a/src/lib/crypto/builtin/des/d3_kysched.c b/src/lib/crypto/builtin/des/d3_kysched.c
new file mode 100644
index 000000000000..ebd1050b1fd9
--- /dev/null
+++ b/src/lib/crypto/builtin/des/d3_kysched.c
@@ -0,0 +1,51 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 1995 by Richard P. Basch. All Rights Reserved.
+ * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Richard P. Basch,
+ * Lehman Brothers and M.I.T. make no representations about the suitability
+ * of this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include "k5-int.h"
+#include "des_int.h"
+
+int
+mit_des3_key_sched(mit_des3_cblock k, mit_des3_key_schedule schedule)
+{
+ mit_des_make_key_sched(k[0],schedule[0]);
+ mit_des_make_key_sched(k[1],schedule[1]);
+ mit_des_make_key_sched(k[2],schedule[2]);
+
+ if (!mit_des_check_key_parity(k[0])) /* bad parity --> return -1 */
+ return(-1);
+ if (mit_des_is_weak_key(k[0]))
+ return(-2);
+
+ if (!mit_des_check_key_parity(k[1]))
+ return(-1);
+ if (mit_des_is_weak_key(k[1]))
+ return(-2);
+
+ if (!mit_des_check_key_parity(k[2]))
+ return(-1);
+ if (mit_des_is_weak_key(k[2]))
+ return(-2);
+
+ /* if key was good, return 0 */
+ return 0;
+}
diff --git a/src/lib/crypto/builtin/des/deps b/src/lib/crypto/builtin/des/deps
new file mode 100644
index 000000000000..df2a31dacda9
--- /dev/null
+++ b/src/lib/crypto/builtin/des/deps
@@ -0,0 +1,148 @@
+#
+# Generated makefile dependencies follow.
+#
+d3_aead.so d3_aead.po $(OUTPRE)d3_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
+ $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ d3_aead.c des_int.h f_tables.h
+d3_kysched.so d3_kysched.po $(OUTPRE)d3_kysched.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ d3_kysched.c des_int.h
+des_keys.so des_keys.po $(OUTPRE)des_keys.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../aes/aes.h \
+ $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ des_int.h des_keys.c
+f_aead.so f_aead.po $(OUTPRE)f_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
+ $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ des_int.h f_aead.c f_tables.h
+f_cksum.so f_cksum.po $(OUTPRE)f_cksum.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h des_int.h f_cksum.c \
+ f_tables.h
+f_parity.so f_parity.po $(OUTPRE)f_parity.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ des_int.h f_parity.c
+f_sched.so f_sched.po $(OUTPRE)f_sched.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h des_int.h f_sched.c
+f_tables.so f_tables.po $(OUTPRE)f_tables.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ des_int.h f_tables.c f_tables.h
+key_sched.so key_sched.po $(OUTPRE)key_sched.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ des_int.h key_sched.c
+weak_key.so weak_key.po $(OUTPRE)weak_key.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ des_int.h weak_key.c
+destest.so destest.po $(OUTPRE)destest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h des_int.h destest.c
+f_cbc.so f_cbc.po $(OUTPRE)f_cbc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h des_int.h f_cbc.c \
+ f_tables.h
+t_verify.so t_verify.po $(OUTPRE)t_verify.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ des_int.h t_verify.c
diff --git a/src/lib/crypto/builtin/des/des_int.h b/src/lib/crypto/builtin/des/des_int.h
new file mode 100644
index 000000000000..0801cb5828c9
--- /dev/null
+++ b/src/lib/crypto/builtin/des/des_int.h
@@ -0,0 +1,286 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/des_int.h */
+/*
+ * Copyright 1987, 1988, 1990, 2002 by the Massachusetts Institute of
+ * Technology. All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Private include file for the Data Encryption Standard library. */
+
+/* only do the whole thing once */
+#ifndef DES_INTERNAL_DEFS
+#define DES_INTERNAL_DEFS
+
+#include "k5-int.h"
+/*
+ * Begin "mit-des.h"
+ */
+#ifndef KRB5_MIT_DES__
+#define KRB5_MIT_DES__
+
+#if defined(__MACH__) && defined(__APPLE__)
+#include <TargetConditionals.h>
+#include <AvailabilityMacros.h>
+#if TARGET_RT_MAC_CFM
+#error "Use KfM 4.0 SDK headers for CFM compilation."
+#endif
+#if defined(DEPRECATED_IN_MAC_OS_X_VERSION_10_5) && !defined(KRB5_SUPRESS_DEPRECATED_WARNINGS)
+#define KRB5INT_DES_DEPRECATED DEPRECATED_IN_MAC_OS_X_VERSION_10_5
+#endif
+#endif /* defined(__MACH__) && defined(__APPLE__) */
+
+/* Macro to add deprecated attribute to DES types and functions */
+/* Currently only defined on Mac OS X 10.5 and later. */
+#ifndef KRB5INT_DES_DEPRECATED
+#define KRB5INT_DES_DEPRECATED
+#endif
+
+#include <limits.h>
+
+#if UINT_MAX >= 0xFFFFFFFFUL
+#define DES_INT32 int
+#define DES_UINT32 unsigned int
+#else
+#define DES_INT32 long
+#define DES_UINT32 unsigned long
+#endif
+
+typedef unsigned char des_cblock[8] /* crypto-block size */
+KRB5INT_DES_DEPRECATED;
+
+/*
+ * Key schedule.
+ *
+ * This used to be
+ *
+ * typedef struct des_ks_struct {
+ * union { DES_INT32 pad; des_cblock _;} __;
+ * } des_key_schedule[16];
+ *
+ * but it would cause trouble if DES_INT32 were ever more than 4
+ * bytes. The reason is that all the encryption functions cast it to
+ * (DES_INT32 *), and treat it as if it were DES_INT32[32]. If
+ * 2*sizeof(DES_INT32) is ever more than sizeof(des_cblock), the
+ * caller-allocated des_key_schedule will be overflowed by the key
+ * scheduling functions. We can't assume that every platform will
+ * have an exact 32-bit int, and nothing should be looking inside a
+ * des_key_schedule anyway.
+ */
+typedef struct des_ks_struct { DES_INT32 _[2]; } des_key_schedule[16]
+KRB5INT_DES_DEPRECATED;
+
+typedef des_cblock mit_des_cblock;
+typedef des_key_schedule mit_des_key_schedule;
+
+/* Triple-DES structures */
+typedef mit_des_cblock mit_des3_cblock[3];
+typedef mit_des_key_schedule mit_des3_key_schedule[3];
+
+#define MIT_DES_ENCRYPT 1
+#define MIT_DES_DECRYPT 0
+
+typedef struct mit_des_ran_key_seed {
+ krb5_encrypt_block eblock;
+ krb5_data sequence;
+} mit_des_random_state;
+
+/* the first byte of the key is already in the keyblock */
+
+#define MIT_DES_BLOCK_LENGTH (8*sizeof(krb5_octet))
+#define MIT_DES_CBC_CRC_PAD_MINIMUM CRC32_CKSUM_LENGTH
+/* This used to be 8*sizeof(krb5_octet) */
+#define MIT_DES_KEYSIZE 8
+
+#define MIT_DES_CBC_CKSUM_LENGTH (4*sizeof(krb5_octet))
+
+#endif /* KRB5_MIT_DES__ */
+/*
+ * End "mit-des.h"
+ */
+
+/* afsstring2key.c */
+krb5_error_code mit_afs_string_to_key(krb5_keyblock *keyblock,
+ const krb5_data *data,
+ const krb5_data *salt);
+char *mit_afs_crypt(const char *pw, const char *salt, char *iobuf);
+
+/* f_cksum.c */
+unsigned long mit_des_cbc_cksum(const krb5_octet *, krb5_octet *,
+ unsigned long, const mit_des_key_schedule,
+ const krb5_octet *);
+
+/* f_cbc.c (used by test programs) */
+int
+mit_des_cbc_encrypt(const mit_des_cblock *in, mit_des_cblock *out,
+ unsigned long length, const mit_des_key_schedule schedule,
+ const mit_des_cblock ivec, int enc);
+
+#define mit_des_zeroblock krb5int_c_mit_des_zeroblock
+extern const mit_des_cblock mit_des_zeroblock;
+
+/* fin_rndkey.c */
+krb5_error_code mit_des_finish_random_key(const krb5_encrypt_block *,
+ krb5_pointer *);
+
+/* finish_key.c */
+krb5_error_code mit_des_finish_key(krb5_encrypt_block *);
+
+/* init_rkey.c */
+krb5_error_code mit_des_init_random_key(const krb5_encrypt_block *,
+ const krb5_keyblock *,
+ krb5_pointer *);
+
+/* key_parity.c */
+void mit_des_fixup_key_parity(mit_des_cblock);
+int mit_des_check_key_parity(mit_des_cblock);
+
+/* key_sched.c */
+int mit_des_key_sched(mit_des_cblock, mit_des_key_schedule);
+
+/* process_ky.c */
+krb5_error_code mit_des_process_key(krb5_encrypt_block *,
+ const krb5_keyblock *);
+
+/* random_key.c */
+krb5_error_code mit_des_random_key(const krb5_encrypt_block *,
+ krb5_pointer, krb5_keyblock **);
+
+/* string2key.c */
+krb5_error_code mit_des_string_to_key(const krb5_encrypt_block *,
+ krb5_keyblock *, const krb5_data *,
+ const krb5_data *);
+krb5_error_code mit_des_string_to_key_int(krb5_keyblock *, const krb5_data *,
+ const krb5_data *);
+
+/* weak_key.c */
+int mit_des_is_weak_key(mit_des_cblock);
+
+/* cmb_keys.c */
+krb5_error_code mit_des_combine_subkeys(const krb5_keyblock *,
+ const krb5_keyblock *,
+ krb5_keyblock **);
+
+/* f_pcbc.c */
+int mit_des_pcbc_encrypt();
+
+/* f_sched.c */
+int mit_des_make_key_sched(mit_des_cblock, mit_des_key_schedule);
+
+
+/* misc.c */
+extern void swap_bits(char *);
+extern unsigned long long_swap_bits(unsigned long);
+extern unsigned long swap_six_bits_to_ansi(unsigned long);
+extern unsigned long swap_four_bits_to_ansi(unsigned long);
+extern unsigned long swap_bit_pos_1(unsigned long);
+extern unsigned long swap_bit_pos_0(unsigned long);
+extern unsigned long swap_bit_pos_0_to_ansi(unsigned long);
+extern unsigned long rev_swap_bit_pos_0(unsigned long);
+extern unsigned long swap_byte_bits(unsigned long);
+extern unsigned long swap_long_bytes_bit_number(unsigned long);
+#ifdef FILE
+/* XXX depends on FILE being a #define! */
+extern void test_set(FILE *, const char *, int, const char *, int);
+#endif
+
+void
+krb5int_des3_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule ks1,
+ const mit_des_key_schedule ks2,
+ const mit_des_key_schedule ks3,
+ mit_des_cblock ivec);
+
+void
+krb5int_des3_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule ks1,
+ const mit_des_key_schedule ks2,
+ const mit_des_key_schedule ks3,
+ mit_des_cblock ivec);
+
+void
+krb5int_des_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule,
+ mit_des_cblock ivec);
+
+void
+krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule,
+ mit_des_cblock ivec);
+
+void
+krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule, mit_des_cblock ivec,
+ mit_des_cblock out);
+
+/* d3_procky.c */
+krb5_error_code mit_des3_process_key(krb5_encrypt_block *eblock,
+ const krb5_keyblock *keyblock);
+
+/* d3_kysched.c */
+int mit_des3_key_sched(mit_des3_cblock key, mit_des3_key_schedule schedule);
+
+/* d3_str2ky.c */
+krb5_error_code mit_des3_string_to_key(const krb5_encrypt_block *eblock,
+ krb5_keyblock *keyblock,
+ const krb5_data *data,
+ const krb5_data *salt);
+
+/* u_nfold.c */
+krb5_error_code mit_des_n_fold(const krb5_octet *input, const size_t in_len,
+ krb5_octet *output, const size_t out_len);
+
+/* u_rn_key.c */
+int mit_des_is_weak_keyblock(krb5_keyblock *keyblock);
+
+void mit_des_fixup_keyblock_parity(krb5_keyblock *keyblock);
+
+krb5_error_code mit_des_set_random_generator_seed(const krb5_data *seed,
+ krb5_pointer random_state);
+
+krb5_error_code mit_des_set_random_sequence_number(const krb5_data *sequence,
+ krb5_pointer random_state);
+#endif /*DES_INTERNAL_DEFS*/
diff --git a/src/lib/crypto/builtin/des/des_keys.c b/src/lib/crypto/builtin/des/des_keys.c
new file mode 100644
index 000000000000..32b119aade70
--- /dev/null
+++ b/src/lib/crypto/builtin/des/des_keys.c
@@ -0,0 +1,40 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/des_keys.c - Key functions used by Kerberos code */
+/*
+ * Copyright (C) 2011 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "crypto_int.h"
+#include "des_int.h"
+
+void
+k5_des_fixup_key_parity(unsigned char *keybits)
+{
+ mit_des_fixup_key_parity(keybits);
+}
+
+krb5_boolean
+k5_des_is_weak_key(unsigned char *keybits)
+{
+ return mit_des_is_weak_key(keybits);
+}
diff --git a/src/lib/crypto/builtin/des/destest.c b/src/lib/crypto/builtin/des/destest.c
new file mode 100644
index 000000000000..6eeb070d867f
--- /dev/null
+++ b/src/lib/crypto/builtin/des/destest.c
@@ -0,0 +1,243 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/destest.c */
+/*
+ * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Test a DES implementation against known inputs & outputs. */
+
+#include "des_int.h"
+#include <stdio.h>
+
+void convert (char *, unsigned char []);
+
+void des_cblock_print_file (mit_des_cblock, FILE *);
+
+krb5_octet zeroblock[8] = {0,0,0,0,0,0,0,0};
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char block1[17], block2[17], block3[17];
+#if 0
+ mit_des_cblock key, input, output, output2;
+#else
+ /* Force tests of unaligned accesses. */
+ union { unsigned char c[8*4+3]; long l; } u;
+ unsigned char *ioblocks = u.c;
+ unsigned char *input = ioblocks+1;
+ unsigned char *output = ioblocks+10;
+ unsigned char *output2 = ioblocks+19;
+ unsigned char *key = ioblocks+27;
+#endif
+ mit_des_key_schedule sched;
+ int num = 0;
+ int retval;
+
+ int error = 0;
+
+ while (scanf("%16s %16s %16s", block1, block2, block3) == 3) {
+ convert(block1, key);
+ convert(block2, input);
+ convert(block3, output);
+
+ retval = mit_des_key_sched(key, sched);
+ if (retval) {
+ fprintf(stderr, "des test: can't process key: %d\n", retval);
+ fprintf(stderr, "des test: %s %s %s\n", block1, block2, block3);
+ exit(1);
+ }
+ mit_des_cbc_encrypt((const mit_des_cblock *) input,
+ (mit_des_cblock *) output2, 8,
+ sched, zeroblock, 1);
+
+ if (memcmp((char *)output2, (char *)output, 8)) {
+ fprintf(stderr,
+ "DES ENCRYPT ERROR, key %s, text %s, real cipher %s, computed cyphertext %02X%02X%02X%02X%02X%02X%02X%02X\n",
+ block1, block2, block3,
+ output2[0],output2[1],output2[2],output2[3],
+ output2[4],output2[5],output2[6],output2[7]);
+ error++;
+ }
+
+ /*
+ * Now try decrypting....
+ */
+ mit_des_cbc_encrypt((const mit_des_cblock *) output,
+ (mit_des_cblock *) output2, 8,
+ sched, zeroblock, 0);
+
+ if (memcmp((char *)output2, (char *)input, 8)) {
+ fprintf(stderr,
+ "DES DECRYPT ERROR, key %s, text %s, real cipher %s, computed cleartext %02X%02X%02X%02X%02X%02X%02X%02X\n",
+ block1, block2, block3,
+ output2[0],output2[1],output2[2],output2[3],
+ output2[4],output2[5],output2[6],output2[7]);
+ error++;
+ }
+
+ num++;
+ }
+
+ if (error)
+ printf("destest: failed to pass the test\n");
+ else
+ printf("destest: %d tests passed successfully\n", num);
+
+ exit( (error > 256 && error % 256) ? 1 : error);
+}
+
+int value[128] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
+void
+convert(text, cblock)
+ char *text;
+ unsigned char cblock[];
+{
+ register int i;
+ for (i = 0; i < 8; i++) {
+ if (text[i*2] < 0 || text[i*2] >= 128)
+ abort ();
+ if (value[(int) text[i*2]] == -1 || value[(int) text[i*2+1]] == -1) {
+ printf("Bad value byte %d in %s\n", i, text);
+ exit(1);
+ }
+ cblock[i] = 16*value[(int) text[i*2]] + value[(int) text[i*2+1]];
+ }
+ return;
+}
+
+/*
+ * Fake out the DES library, for the purposes of testing.
+ */
+
+int
+mit_des_is_weak_key(key)
+ mit_des_cblock key;
+{
+ return 0; /* fake it out for testing */
+}
+
+void
+des_cblock_print_file(x, fp)
+ mit_des_cblock x;
+ FILE *fp;
+{
+ unsigned char *y = (unsigned char *) x;
+ register int i = 0;
+ fprintf(fp," 0x { ");
+
+ while (i++ < 8) {
+ fprintf(fp,"%x",*y++);
+ if (i < 8)
+ fprintf(fp,", ");
+ }
+ fprintf(fp," }");
+}
+
+
+#define smask(step) ((1<<step)-1)
+#define pstep(x,step) (((x)&smask(step))^(((x)>>step)&smask(step)))
+#define parity_char(x) pstep(pstep(pstep((x),4),2),1)
+
+/*
+ * des_check_key_parity: returns true iff key has the correct des parity.
+ * See des_fix_key_parity for the definition of
+ * correct des parity.
+ */
+int
+mit_des_check_key_parity(key)
+ register mit_des_cblock key;
+{
+ unsigned int i;
+
+ for (i=0; i<sizeof(mit_des_cblock); i++) {
+ if ((key[i] & 1) == parity_char(0xfe&key[i])) {
+ printf("warning: bad parity key:");
+ des_cblock_print_file(key, stdout);
+ putchar('\n');
+
+ return 1;
+ }
+ }
+
+ return(1);
+}
+
+void
+mit_des_fixup_key_parity(key)
+ register mit_des_cblock key;
+{
+ unsigned int i;
+ for (i=0; i<sizeof(mit_des_cblock); i++)
+ {
+ key[i] &= 0xfe;
+ key[i] |= 1^parity_char(key[i]);
+ }
+
+ return;
+}
diff --git a/src/lib/crypto/builtin/des/doc/libdes.doc b/src/lib/crypto/builtin/des/doc/libdes.doc
new file mode 100644
index 000000000000..70f9f336a1ea
--- /dev/null
+++ b/src/lib/crypto/builtin/des/doc/libdes.doc
@@ -0,0 +1,208 @@
+
+ How to use the Kerberos encryption library.
+
+ Revised 10/15/85 spm
+
+1) The following include file is needed:
+
+ /projects/auth/include/des.h (VAX)
+ --------------- (PC8086)
+
+2) The encryption library that should be linked to is:
+
+ /projects/auth/lib/libdes.a (VAX)
+| /projects/auth/ibm/lib/libdes.a (PC8086 cross-compilation environment)
+
+3) For each key that may be simultaneously active,
+ allocate (either compile or malloc) a "Key_schedule" struct,
+ defined in "des.h"
+
+4) Create key schedules, as needed, prior to using the encryption
+ routines, via "des_set_key()".
+
+5) Setup the input and output areas. Make sure to note the restrictions
+ on lengths being multiples of eight bytes.
+
+6) Invoke the encryption/decryption routines, "ecb_encrypt()"
+ or "cbc_encrypt()"
+
+7) To generate a cryptographic checksum, use "cbc_cksum()"
+/* ---------------------------------------------------------------- */
+
+ Routine Interfaces--
+
+/* ----------------------------------------------------------------- */
+
+int
+ des_set_key(k,schedule)
+ C_Block *k;
+ Key_schedule schedule;
+
+ Calculates a key schedule from (all) eight bytes of the input key, and
+ puts it into the indicated "Key_schedule" struct;
+
+ Make sure to pass valid eight bytes, no padding or other processing
+ it done.
+
+ The key schedule is then used in subsequent encryption/decryption
+ operations. Many key schedules may be created and cached for later
+ use.
+
+ The user is responsible to clear keys and schedules no longer needed
+ to prevent their disclosure.
+
+| Checks the parity of the key provided, to make sure it is odd per
+| FIPS spec. Returns 0 value for key ok, 1 for key_parity error.
+
+/* ---------------------------------------------------------------- */
+
+int
+ ecb_encrypt(input,output,schedule,encrypt)
+ C_Block *input; /* ptr to eight byte input value */
+ C_Block *output; /* ptr to eight byte output value */
+ int encrypt; /* 0 ==> decrypt, else encrypt */
+ Key_schedule schedule; /* addr of key schedule */
+
+This is the low level routine that encrypts or decrypts a single 8-byte
+block in electronic code book mode. Always transforms the input
+data into the output data.
+
+If encrypt is non-zero, the input (cleartext) is encrypted into the
+output (ciphertext) using the specified key_schedule, pre-set via "des_set_key".
+
+If encrypt is zero, the input (now ciphertext) is decrypted into
+the output (now cleartext).
+
+Input and output may be the same space.
+
+Does not return any meaningful value. Void is not used for compatibility
+with other compilers.
+
+/* -------------------------------------------------------------- */
+
+int
+ cbc_encrypt(input,output,length,schedule,ivec,encrypt)
+
+ C_Block *input; /* ptr to input data */
+ C_Block *output; /* ptr to output data */
+ int length; /* desired length, in bytes */
+ Key_schedule schedule; /* addr of precomputed schedule */
+ C_Block *ivec; /* pointer to 8 byte initialization
+ * vector
+ */
+ int encrypt /* 0 ==> decrypt; else encrypt*/
+
+
+ If encrypt is non-zero, the routine cipher-block-chain encrypts
+ the INPUT (cleartext) into the OUTPUT (ciphertext) using the provided
+ key schedule and initialization vector. If the length is not an integral
+ multiple of eight bytes, the last block is copied to a temp and zero
+ filled (highest addresses). The output is ALWAYS an integral multiple
+ of eight bytes.
+
+ If encrypt is zero, the routine cipher-block chain decrypts the INPUT
+ (ciphertext) into the OUTPUT (cleartext) using the provided key schedule
+ and initialization vector. Decryption ALWAYS operates on integral
+ multiples of 8 bytes, so will round the length provided up to the
+ appropriate multiple. Consequently, it will always produce the rounded-up
+ number of bytes of output cleartext. The application must determine if
+ the output cleartext was zero-padded due to cleartext lengths not integral
+ multiples of 8.
+
+ No errors or meaningful value are returned. Void is not used for
+ compatibility with other compilers.
+
+
+/* cbc checksum (MAC) only routine ---------------------------------------- */
+int
+ cbc_cksum(input,output,length,schedule,ivec)
+
+ C_Block *input; /* >= length bytes of inputtext */
+ C_Block *output; /* >= length bytes of outputtext */
+ int length; /* in bytes */
+ Key_schedule schedule; /* precomputed key schedule */
+ C_Block *ivec; /* 8 bytes of ivec */
+
+
+ Produces a cryptographic checksum, 8 bytes, by cipher-block-chain
+ encrypting the input, discarding the ciphertext output, and only retaining
+ the last ciphertext 8-byte block. Uses the provided key schedule and ivec.
+ The input is effectively zero-padded to an integral multiple of
+ eight bytes, though the original input is not modified.
+
+ No meaningful value is returned. Void is not used for compatibility
+ with other compilers.
+
+
+/* random_key ----------------------------------------*/
+int
+ random_key(key)
+
+ C_Block *key;
+
+ The start for the random number generated is set from the current time
+ in microseconds, then the random number generator is invoked
+ to create an eight byte output key (not a schedule). The key
+ generated is set to odd parity per FIPS spec.
+
+ The caller must supply space for the output key, pointed to
+ by "*key", then after getting a new key, call the des_set_key()
+ routine when needed.
+
+ No meaningfull value is returned. Void is not used for compatibility
+ with other compilers.
+
+
+/* string_to_key --------------------------------------------*/
+
+int
+ string_to_key(str,key)
+ register char *str;
+ register C_Block *key;
+
+ This routines converts an arbitrary length, null terminated string
+ to an 8 byte DES key, with each byte parity set to odd, per FIPS spec.
+
+ The algorithm is as follows:
+
+| Take the first 8 bytes and remove the parity (leaving 56 bits).
+| Do the same for the second 8 bytes, and the third, etc. Do this for
+| as many sets of 8 bytes as necessary, filling in the remainder of the
+| last set with nulls. Fold the second set back on the first (i.e. bit
+| 0 over bit 55, and bit 55 over bit 0). Fold the third over the second
+| (bit 0 of the third set is now over bit 0 of the first set). Repeat
+| until you have done this to all sets. Xor the folded sets. Break the
+| result into 8 7 bit bytes, and generate odd parity for each byte. You
+| now have 64 bits. Note that DES takes a 64 bit key, and uses only the
+| non parity bits.
+
+
+/* read_password -------------------------------------------*/
+
+read_password(k,prompt,verify)
+ C_Block *k;
+ char *prompt;
+ int verify;
+
+This routine issues the supplied prompt, turns off echo, if possible, and
+reads an input string. If verify is non-zero, it does it again, for use
+in applications such as changing a password. If verify is non-zero, both
+versions are compared, and the input is requested repeatedly until they
+match. Then, the input string is mapped into a valid DES key, internally
+using the string_to_key routine. The newly created key is copied to the
+area pointed to by parameter "k".
+
+No meaningful value is returned. If an error occurs trying to manipulate
+the terminal echo, the routine forces the process to exit.
+
+/* get_line ------------------------*/
+long get_line(p,max)
+ char *p;
+ long max;
+
+Reads input characters from standard input until either a newline appears or
+else the max length is reached. The characters read are stuffed into
+the string pointed to, which will always be null terminated. The newline
+is not inserted in the string. The max parameter includes the byte needed
+for the null terminator, so allocate and pass one more than the maximum
+string length desired.
diff --git a/src/lib/crypto/builtin/des/f_aead.c b/src/lib/crypto/builtin/des/f_aead.c
new file mode 100644
index 000000000000..71b8dff4d432
--- /dev/null
+++ b/src/lib/crypto/builtin/des/f_aead.c
@@ -0,0 +1,173 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2008 by the Massachusetts Institute of Technology.
+ * Copyright 1995 by Richard P. Basch. All Rights Reserved.
+ * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Richard P. Basch,
+ * Lehman Brothers and M.I.T. make no representations about the suitability
+ * of this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include "crypto_int.h"
+#include "des_int.h"
+#include "f_tables.h"
+
+const mit_des_cblock mit_des_zeroblock /* = all zero */;
+
+void
+krb5int_des_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule,
+ mit_des_cblock ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
+
+ /* Get key pointer here. This won't need to be reinitialized. */
+ kp = (const unsigned DES_INT32 *)schedule;
+
+ /* Initialize left and right with the contents of the initial vector. */
+ ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+ left = load_32_be(ip);
+ right = load_32_be(ip + 4);
+
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* Decompose this block and xor it with the previous ciphertext. */
+ left ^= load_32_be(block);
+ right ^= load_32_be(block + 4);
+
+ /* Encrypt what we have and put back into block. */
+ DES_DO_ENCRYPT(left, right, kp);
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
+
+ k5_iov_cursor_put(&cursor, block);
+ }
+
+ if (ivec != NULL) {
+ store_32_be(left, ivec);
+ store_32_be(right, ivec + 4);
+ }
+}
+
+void
+krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule,
+ mit_des_cblock ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ unsigned DES_INT32 ocipherl, ocipherr;
+ unsigned DES_INT32 cipherl, cipherr;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
+
+ /* Get key pointer here. This won't need to be reinitialized. */
+ kp = (const unsigned DES_INT32 *)schedule;
+
+ /*
+ * Decrypting is harder than encrypting because of
+ * the necessity of remembering a lot more things.
+ * Should think about this a little more...
+ */
+
+ /* Prime the old cipher with ivec. */
+ ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+ ocipherl = load_32_be(ip);
+ ocipherr = load_32_be(ip + 4);
+
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* Split this block into left and right. */
+ cipherl = left = load_32_be(block);
+ cipherr = right = load_32_be(block + 4);
+
+ /* Decrypt and xor with the old cipher to get plain text. */
+ DES_DO_DECRYPT(left, right, kp);
+ left ^= ocipherl;
+ right ^= ocipherr;
+
+ /* Store the encrypted halves back into block. */
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
+
+ /* Save current cipher block halves. */
+ ocipherl = cipherl;
+ ocipherr = cipherr;
+
+ k5_iov_cursor_put(&cursor, block);
+ }
+
+ if (ivec != NULL) {
+ store_32_be(ocipherl, ivec);
+ store_32_be(ocipherr, ivec + 4);
+ }
+}
+
+void
+krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule, mit_des_cblock ivec,
+ mit_des_cblock out)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
+
+ /* Get key pointer here. This won't need to be reinitialized. */
+ kp = (const unsigned DES_INT32 *)schedule;
+
+ /* Initialize left and right with the contents of the initial vector. */
+ ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+ left = load_32_be(ip);
+ right = load_32_be(ip + 4);
+
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, TRUE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* Decompose this block and xor it with the previous ciphertext. */
+ left ^= load_32_be(block);
+ right ^= load_32_be(block + 4);
+
+ /* Encrypt what we have. */
+ DES_DO_ENCRYPT(left, right, kp);
+ }
+
+ /* Output the final ciphertext block. */
+ store_32_be(left, out);
+ store_32_be(right, out + 4);
+}
+
+#if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
+void krb5int_des_do_encrypt_2 (unsigned DES_INT32 *left,
+ unsigned DES_INT32 *right,
+ const unsigned DES_INT32 *kp)
+{
+ DES_DO_ENCRYPT_1 (*left, *right, kp);
+}
+
+void krb5int_des_do_decrypt_2 (unsigned DES_INT32 *left,
+ unsigned DES_INT32 *right,
+ const unsigned DES_INT32 *kp)
+{
+ DES_DO_DECRYPT_1 (*left, *right, kp);
+}
+#endif
diff --git a/src/lib/crypto/builtin/des/f_cbc.c b/src/lib/crypto/builtin/des/f_cbc.c
new file mode 100644
index 000000000000..84d5382f22f4
--- /dev/null
+++ b/src/lib/crypto/builtin/des/f_cbc.c
@@ -0,0 +1,256 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/f_cbc.c */
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * CBC functions; used only by the test programs at this time. (krb5 uses the
+ * functions in f_aead.c instead.)
+ */
+
+/*
+ * des_cbc_encrypt.c - an implementation of the DES cipher function in cbc mode
+ */
+#include "des_int.h"
+#include "f_tables.h"
+
+/*
+ * des_cbc_encrypt - {en,de}crypt a stream in CBC mode
+ */
+
+/*
+ * This routine performs DES cipher-block-chaining operation, either
+ * encrypting from cleartext to ciphertext, if encrypt != 0 or
+ * decrypting from ciphertext to cleartext, if encrypt == 0.
+ *
+ * The key schedule is passed as an arg, as well as the cleartext or
+ * ciphertext. The cleartext and ciphertext should be in host order.
+ *
+ * NOTE-- the output is ALWAYS an multiple of 8 bytes long. If not
+ * enough space was provided, your program will get trashed.
+ *
+ * For encryption, the cleartext string is null padded, at the end, to
+ * an integral multiple of eight bytes.
+ *
+ * For decryption, the ciphertext will be used in integral multiples
+ * of 8 bytes, but only the first "length" bytes returned into the
+ * cleartext.
+ */
+
+const mit_des_cblock mit_des_zeroblock /* = all zero */;
+
+static void
+des_cbc_encrypt(const mit_des_cblock *in, mit_des_cblock *out,
+ unsigned long length, const mit_des_key_schedule schedule,
+ const mit_des_cblock ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ unsigned char *op;
+
+ /*
+ * Get key pointer here. This won't need to be reinitialized
+ */
+ kp = (const unsigned DES_INT32 *)schedule;
+
+ /*
+ * Initialize left and right with the contents of the initial
+ * vector.
+ */
+ ip = ivec;
+ GET_HALF_BLOCK(left, ip);
+ GET_HALF_BLOCK(right, ip);
+
+ /*
+ * Suitably initialized, now work the length down 8 bytes
+ * at a time.
+ */
+ ip = *in;
+ op = *out;
+ while (length > 0) {
+ /*
+ * Get more input, xor it in. If the length is
+ * greater than or equal to 8 this is straight
+ * forward. Otherwise we have to fart around.
+ */
+ if (length >= 8) {
+ unsigned DES_INT32 temp;
+ GET_HALF_BLOCK(temp, ip);
+ left ^= temp;
+ GET_HALF_BLOCK(temp, ip);
+ right ^= temp;
+ length -= 8;
+ } else {
+ /*
+ * Oh, shoot. We need to pad the
+ * end with zeroes. Work backwards
+ * to do this.
+ */
+ ip += (int) length;
+ switch(length) {
+ case 7:
+ right ^= (*(--ip) & FF_UINT32) << 8;
+ case 6:
+ right ^= (*(--ip) & FF_UINT32) << 16;
+ case 5:
+ right ^= (*(--ip) & FF_UINT32) << 24;
+ case 4:
+ left ^= *(--ip) & FF_UINT32;
+ case 3:
+ left ^= (*(--ip) & FF_UINT32) << 8;
+ case 2:
+ left ^= (*(--ip) & FF_UINT32) << 16;
+ case 1:
+ left ^= (*(--ip) & FF_UINT32) << 24;
+ break;
+ }
+ length = 0;
+ }
+
+ /*
+ * Encrypt what we have
+ */
+ DES_DO_ENCRYPT(left, right, kp);
+
+ /*
+ * Copy the results out
+ */
+ PUT_HALF_BLOCK(left, op);
+ PUT_HALF_BLOCK(right, op);
+ }
+}
+
+static void
+des_cbc_decrypt(const mit_des_cblock *in, mit_des_cblock *out,
+ unsigned long length, const mit_des_key_schedule schedule,
+ const mit_des_cblock ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ unsigned char *op;
+ unsigned DES_INT32 ocipherl, ocipherr;
+ unsigned DES_INT32 cipherl, cipherr;
+
+ /*
+ * Get key pointer here. This won't need to be reinitialized
+ */
+ kp = (const unsigned DES_INT32 *)schedule;
+
+ /*
+ * Decrypting is harder than encrypting because of
+ * the necessity of remembering a lot more things.
+ * Should think about this a little more...
+ */
+
+ if (length <= 0)
+ return;
+
+ /*
+ * Prime the old cipher with ivec.
+ */
+ ip = ivec;
+ GET_HALF_BLOCK(ocipherl, ip);
+ GET_HALF_BLOCK(ocipherr, ip);
+
+ /*
+ * Now do this in earnest until we run out of length.
+ */
+ ip = *in;
+ op = *out;
+ for (;;) { /* check done inside loop */
+ /*
+ * Read a block from the input into left and
+ * right. Save this cipher block for later.
+ */
+ GET_HALF_BLOCK(left, ip);
+ GET_HALF_BLOCK(right, ip);
+ cipherl = left;
+ cipherr = right;
+
+ /*
+ * Decrypt this.
+ */
+ DES_DO_DECRYPT(left, right, kp);
+
+ /*
+ * Xor with the old cipher to get plain
+ * text. Output 8 or less bytes of this.
+ */
+ left ^= ocipherl;
+ right ^= ocipherr;
+ if (length > 8) {
+ length -= 8;
+ PUT_HALF_BLOCK(left, op);
+ PUT_HALF_BLOCK(right, op);
+ /*
+ * Save current cipher block here
+ */
+ ocipherl = cipherl;
+ ocipherr = cipherr;
+ } else {
+ /*
+ * Trouble here. Start at end of output,
+ * work backwards.
+ */
+ op += (int) length;
+ switch(length) {
+ case 8:
+ *(--op) = (unsigned char) (right & 0xff);
+ case 7:
+ *(--op) = (unsigned char) ((right >> 8) & 0xff);
+ case 6:
+ *(--op) = (unsigned char) ((right >> 16) & 0xff);
+ case 5:
+ *(--op) = (unsigned char) ((right >> 24) & 0xff);
+ case 4:
+ *(--op) = (unsigned char) (left & 0xff);
+ case 3:
+ *(--op) = (unsigned char) ((left >> 8) & 0xff);
+ case 2:
+ *(--op) = (unsigned char) ((left >> 16) & 0xff);
+ case 1:
+ *(--op) = (unsigned char) ((left >> 24) & 0xff);
+ break;
+ }
+ break; /* we're done */
+ }
+ }
+}
+
+int
+mit_des_cbc_encrypt(const mit_des_cblock *in, mit_des_cblock *out,
+ unsigned long length, const mit_des_key_schedule schedule,
+ const mit_des_cblock ivec, int enc)
+{
+ /*
+ * Deal with encryption and decryption separately.
+ */
+ if (enc)
+ des_cbc_encrypt(in, out, length, schedule, ivec);
+ else
+ des_cbc_decrypt(in, out, length, schedule, ivec);
+ return 0;
+}
diff --git a/src/lib/crypto/builtin/des/f_cksum.c b/src/lib/crypto/builtin/des/f_cksum.c
new file mode 100644
index 000000000000..4492ce6df41b
--- /dev/null
+++ b/src/lib/crypto/builtin/des/f_cksum.c
@@ -0,0 +1,136 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/f_cksum.c */
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* DES implementation donated by Dennis Ferguson */
+
+/*
+ * des_cbc_cksum.c - compute an 8 byte checksum using DES in CBC mode
+ */
+#include "des_int.h"
+#include "f_tables.h"
+
+/*
+ * This routine performs DES cipher-block-chaining checksum operation,
+ * a.k.a. Message Authentication Code. It ALWAYS encrypts from input
+ * to a single 64 bit output MAC checksum.
+ *
+ * The key schedule is passed as an arg, as well as the cleartext or
+ * ciphertext. The cleartext and ciphertext should be in host order.
+ *
+ * NOTE-- the output is ALWAYS 8 bytes long. If not enough space was
+ * provided, your program will get trashed.
+ *
+ * The input is null padded, at the end (highest addr), to an integral
+ * multiple of eight bytes.
+ */
+
+unsigned long
+mit_des_cbc_cksum(const krb5_octet *in, krb5_octet *out,
+ unsigned long length, const mit_des_key_schedule schedule,
+ const krb5_octet *ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ unsigned char *op;
+ register DES_INT32 len;
+
+ /*
+ * Initialize left and right with the contents of the initial
+ * vector.
+ */
+ ip = ivec;
+ GET_HALF_BLOCK(left, ip);
+ GET_HALF_BLOCK(right, ip);
+
+ /*
+ * Suitably initialized, now work the length down 8 bytes
+ * at a time.
+ */
+ ip = in;
+ len = length;
+ while (len > 0) {
+ /*
+ * Get more input, xor it in. If the length is
+ * greater than or equal to 8 this is straight
+ * forward. Otherwise we have to fart around.
+ */
+ if (len >= 8) {
+ unsigned DES_INT32 temp;
+ GET_HALF_BLOCK(temp, ip);
+ left ^= temp;
+ GET_HALF_BLOCK(temp, ip);
+ right ^= temp;
+ len -= 8;
+ } else {
+ /*
+ * Oh, shoot. We need to pad the
+ * end with zeroes. Work backwards
+ * to do this.
+ */
+ ip += (int) len;
+ switch(len) {
+ case 7:
+ right ^= (*(--ip) & FF_UINT32) << 8;
+ case 6:
+ right ^= (*(--ip) & FF_UINT32) << 16;
+ case 5:
+ right ^= (*(--ip) & FF_UINT32) << 24;
+ case 4:
+ left ^= *(--ip) & FF_UINT32;
+ case 3:
+ left ^= (*(--ip) & FF_UINT32) << 8;
+ case 2:
+ left ^= (*(--ip) & FF_UINT32) << 16;
+ case 1:
+ left ^= (*(--ip) & FF_UINT32) << 24;
+ break;
+ }
+ len = 0;
+ }
+
+ /*
+ * Encrypt what we have
+ */
+ kp = (const unsigned DES_INT32 *)schedule;
+ DES_DO_ENCRYPT(left, right, kp);
+ }
+
+ /*
+ * Done. Left and right have the checksum. Put it into
+ * the output.
+ */
+ op = out;
+ PUT_HALF_BLOCK(left, op);
+ PUT_HALF_BLOCK(right, op);
+
+ /*
+ * Return right. I'll bet the MIT code returns this
+ * inconsistantly (with the low order byte of the checksum
+ * not always in the low order byte of the DES_INT32). We won't.
+ */
+ return right & 0xFFFFFFFFUL;
+}
diff --git a/src/lib/crypto/builtin/des/f_parity.c b/src/lib/crypto/builtin/des/f_parity.c
new file mode 100644
index 000000000000..460b5061b5bc
--- /dev/null
+++ b/src/lib/crypto/builtin/des/f_parity.c
@@ -0,0 +1,56 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * These routines check and fix parity of encryption keys for the DES
+ * algorithm.
+ *
+ * They are a replacement for routines in key_parity.c, that don't require
+ * the table building that they do.
+ *
+ * Mark Eichin -- Cygnus Support
+ */
+
+
+#include "des_int.h"
+
+/*
+ * des_fixup_key_parity: Forces odd parity per byte; parity is bits
+ * 8,16,...64 in des order, implies 0, 8, 16, ...
+ * vax order.
+ */
+#define smask(step) ((1<<step)-1)
+#define pstep(x,step) (((x)&smask(step))^(((x)>>step)&smask(step)))
+#define parity_char(x) pstep(pstep(pstep((x),4),2),1)
+
+void
+mit_des_fixup_key_parity(mit_des_cblock key)
+{
+ unsigned int i;
+ for (i=0; i<sizeof(mit_des_cblock); i++)
+ {
+ key[i] &= 0xfe;
+ key[i] |= 1^parity_char(key[i]);
+ }
+
+ return;
+}
+
+/*
+ * des_check_key_parity: returns true iff key has the correct des parity.
+ * See des_fix_key_parity for the definition of
+ * correct des parity.
+ */
+int
+mit_des_check_key_parity(mit_des_cblock key)
+{
+ unsigned int i;
+
+ for (i=0; i<sizeof(mit_des_cblock); i++)
+ {
+ if((key[i] & 1) == parity_char(0xfe&key[i]))
+ {
+ return 0;
+ }
+ }
+
+ return(1);
+}
diff --git a/src/lib/crypto/builtin/des/f_sched.c b/src/lib/crypto/builtin/des/f_sched.c
new file mode 100644
index 000000000000..89d820f45957
--- /dev/null
+++ b/src/lib/crypto/builtin/des/f_sched.c
@@ -0,0 +1,359 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/f_sched.c */
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* DES implementation donated by Dennis Ferguson */
+
+/*
+ * des_make_sched.c - permute a DES key, returning the resulting key schedule
+ */
+#include "k5-int.h"
+#include "des_int.h"
+
+/*
+ * Permuted choice 1 tables. These are used to extract bits
+ * from the left and right parts of the key to form Ci and Di.
+ * The code that uses these tables knows which bits from which
+ * part of each key are used to form Ci and Di.
+ */
+static const unsigned DES_INT32 PC1_CL[8] = {
+ 0x00000000, 0x00000010, 0x00001000, 0x00001010,
+ 0x00100000, 0x00100010, 0x00101000, 0x00101010
+};
+
+static const unsigned DES_INT32 PC1_DL[16] = {
+ 0x00000000, 0x00100000, 0x00001000, 0x00101000,
+ 0x00000010, 0x00100010, 0x00001010, 0x00101010,
+ 0x00000001, 0x00100001, 0x00001001, 0x00101001,
+ 0x00000011, 0x00100011, 0x00001011, 0x00101011
+};
+
+static const unsigned DES_INT32 PC1_CR[16] = {
+ 0x00000000, 0x00000001, 0x00000100, 0x00000101,
+ 0x00010000, 0x00010001, 0x00010100, 0x00010101,
+ 0x01000000, 0x01000001, 0x01000100, 0x01000101,
+ 0x01010000, 0x01010001, 0x01010100, 0x01010101
+};
+
+static const unsigned DES_INT32 PC1_DR[8] = {
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100
+};
+
+
+/*
+ * At the start of some iterations of the key schedule we do
+ * a circular left shift by one place, while for others we do a shift by
+ * two places. This has bits set for the iterations where we do 2 bit
+ * shifts, starting at the low order bit.
+ */
+#define TWO_BIT_SHIFTS 0x7efc
+
+/*
+ * Permuted choice 2 tables. The first actually produces the low order
+ * 24 bits of the subkey Ki from the 28 bit value of Ci. The second produces
+ * the high order 24 bits from Di. The tables are indexed by six bit
+ * segments of Ci and Di respectively. The code is handcrafted to compute
+ * the appropriate 6 bit chunks.
+ *
+ * Note that for ease of computation, the 24 bit values are produced with
+ * six bits going into each byte. Note also that the table has been byte
+ * rearranged to produce keys which match the order we will apply them
+ * in in the des code.
+ */
+static const unsigned DES_INT32 PC2_C[4][64] = {
+ {
+ 0x00000000, 0x00000004, 0x00010000, 0x00010004,
+ 0x00000400, 0x00000404, 0x00010400, 0x00010404,
+ 0x00000020, 0x00000024, 0x00010020, 0x00010024,
+ 0x00000420, 0x00000424, 0x00010420, 0x00010424,
+ 0x01000000, 0x01000004, 0x01010000, 0x01010004,
+ 0x01000400, 0x01000404, 0x01010400, 0x01010404,
+ 0x01000020, 0x01000024, 0x01010020, 0x01010024,
+ 0x01000420, 0x01000424, 0x01010420, 0x01010424,
+ 0x00020000, 0x00020004, 0x00030000, 0x00030004,
+ 0x00020400, 0x00020404, 0x00030400, 0x00030404,
+ 0x00020020, 0x00020024, 0x00030020, 0x00030024,
+ 0x00020420, 0x00020424, 0x00030420, 0x00030424,
+ 0x01020000, 0x01020004, 0x01030000, 0x01030004,
+ 0x01020400, 0x01020404, 0x01030400, 0x01030404,
+ 0x01020020, 0x01020024, 0x01030020, 0x01030024,
+ 0x01020420, 0x01020424, 0x01030420, 0x01030424,
+ },
+ {
+ 0x00000000, 0x02000000, 0x00000800, 0x02000800,
+ 0x00080000, 0x02080000, 0x00080800, 0x02080800,
+ 0x00000001, 0x02000001, 0x00000801, 0x02000801,
+ 0x00080001, 0x02080001, 0x00080801, 0x02080801,
+ 0x00000100, 0x02000100, 0x00000900, 0x02000900,
+ 0x00080100, 0x02080100, 0x00080900, 0x02080900,
+ 0x00000101, 0x02000101, 0x00000901, 0x02000901,
+ 0x00080101, 0x02080101, 0x00080901, 0x02080901,
+ 0x10000000, 0x12000000, 0x10000800, 0x12000800,
+ 0x10080000, 0x12080000, 0x10080800, 0x12080800,
+ 0x10000001, 0x12000001, 0x10000801, 0x12000801,
+ 0x10080001, 0x12080001, 0x10080801, 0x12080801,
+ 0x10000100, 0x12000100, 0x10000900, 0x12000900,
+ 0x10080100, 0x12080100, 0x10080900, 0x12080900,
+ 0x10000101, 0x12000101, 0x10000901, 0x12000901,
+ 0x10080101, 0x12080101, 0x10080901, 0x12080901,
+ },
+ {
+ 0x00000000, 0x00040000, 0x00002000, 0x00042000,
+ 0x00100000, 0x00140000, 0x00102000, 0x00142000,
+ 0x20000000, 0x20040000, 0x20002000, 0x20042000,
+ 0x20100000, 0x20140000, 0x20102000, 0x20142000,
+ 0x00000008, 0x00040008, 0x00002008, 0x00042008,
+ 0x00100008, 0x00140008, 0x00102008, 0x00142008,
+ 0x20000008, 0x20040008, 0x20002008, 0x20042008,
+ 0x20100008, 0x20140008, 0x20102008, 0x20142008,
+ 0x00200000, 0x00240000, 0x00202000, 0x00242000,
+ 0x00300000, 0x00340000, 0x00302000, 0x00342000,
+ 0x20200000, 0x20240000, 0x20202000, 0x20242000,
+ 0x20300000, 0x20340000, 0x20302000, 0x20342000,
+ 0x00200008, 0x00240008, 0x00202008, 0x00242008,
+ 0x00300008, 0x00340008, 0x00302008, 0x00342008,
+ 0x20200008, 0x20240008, 0x20202008, 0x20242008,
+ 0x20300008, 0x20340008, 0x20302008, 0x20342008,
+ },
+ {
+ 0x00000000, 0x00000010, 0x08000000, 0x08000010,
+ 0x00000200, 0x00000210, 0x08000200, 0x08000210,
+ 0x00000002, 0x00000012, 0x08000002, 0x08000012,
+ 0x00000202, 0x00000212, 0x08000202, 0x08000212,
+ 0x04000000, 0x04000010, 0x0c000000, 0x0c000010,
+ 0x04000200, 0x04000210, 0x0c000200, 0x0c000210,
+ 0x04000002, 0x04000012, 0x0c000002, 0x0c000012,
+ 0x04000202, 0x04000212, 0x0c000202, 0x0c000212,
+ 0x00001000, 0x00001010, 0x08001000, 0x08001010,
+ 0x00001200, 0x00001210, 0x08001200, 0x08001210,
+ 0x00001002, 0x00001012, 0x08001002, 0x08001012,
+ 0x00001202, 0x00001212, 0x08001202, 0x08001212,
+ 0x04001000, 0x04001010, 0x0c001000, 0x0c001010,
+ 0x04001200, 0x04001210, 0x0c001200, 0x0c001210,
+ 0x04001002, 0x04001012, 0x0c001002, 0x0c001012,
+ 0x04001202, 0x04001212, 0x0c001202, 0x0c001212
+ },
+};
+
+static const unsigned DES_INT32 PC2_D[4][64] = {
+ {
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000100, 0x02000100, 0x00020100, 0x02020100,
+ 0x00000008, 0x02000008, 0x00020008, 0x02020008,
+ 0x00000108, 0x02000108, 0x00020108, 0x02020108,
+ 0x00200000, 0x02200000, 0x00220000, 0x02220000,
+ 0x00200100, 0x02200100, 0x00220100, 0x02220100,
+ 0x00200008, 0x02200008, 0x00220008, 0x02220008,
+ 0x00200108, 0x02200108, 0x00220108, 0x02220108,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000300, 0x02000300, 0x00020300, 0x02020300,
+ 0x00000208, 0x02000208, 0x00020208, 0x02020208,
+ 0x00000308, 0x02000308, 0x00020308, 0x02020308,
+ 0x00200200, 0x02200200, 0x00220200, 0x02220200,
+ 0x00200300, 0x02200300, 0x00220300, 0x02220300,
+ 0x00200208, 0x02200208, 0x00220208, 0x02220208,
+ 0x00200308, 0x02200308, 0x00220308, 0x02220308,
+ },
+ {
+ 0x00000000, 0x00001000, 0x00000020, 0x00001020,
+ 0x00100000, 0x00101000, 0x00100020, 0x00101020,
+ 0x08000000, 0x08001000, 0x08000020, 0x08001020,
+ 0x08100000, 0x08101000, 0x08100020, 0x08101020,
+ 0x00000004, 0x00001004, 0x00000024, 0x00001024,
+ 0x00100004, 0x00101004, 0x00100024, 0x00101024,
+ 0x08000004, 0x08001004, 0x08000024, 0x08001024,
+ 0x08100004, 0x08101004, 0x08100024, 0x08101024,
+ 0x00000400, 0x00001400, 0x00000420, 0x00001420,
+ 0x00100400, 0x00101400, 0x00100420, 0x00101420,
+ 0x08000400, 0x08001400, 0x08000420, 0x08001420,
+ 0x08100400, 0x08101400, 0x08100420, 0x08101420,
+ 0x00000404, 0x00001404, 0x00000424, 0x00001424,
+ 0x00100404, 0x00101404, 0x00100424, 0x00101424,
+ 0x08000404, 0x08001404, 0x08000424, 0x08001424,
+ 0x08100404, 0x08101404, 0x08100424, 0x08101424,
+ },
+ {
+ 0x00000000, 0x10000000, 0x00010000, 0x10010000,
+ 0x00000002, 0x10000002, 0x00010002, 0x10010002,
+ 0x00002000, 0x10002000, 0x00012000, 0x10012000,
+ 0x00002002, 0x10002002, 0x00012002, 0x10012002,
+ 0x00040000, 0x10040000, 0x00050000, 0x10050000,
+ 0x00040002, 0x10040002, 0x00050002, 0x10050002,
+ 0x00042000, 0x10042000, 0x00052000, 0x10052000,
+ 0x00042002, 0x10042002, 0x00052002, 0x10052002,
+ 0x20000000, 0x30000000, 0x20010000, 0x30010000,
+ 0x20000002, 0x30000002, 0x20010002, 0x30010002,
+ 0x20002000, 0x30002000, 0x20012000, 0x30012000,
+ 0x20002002, 0x30002002, 0x20012002, 0x30012002,
+ 0x20040000, 0x30040000, 0x20050000, 0x30050000,
+ 0x20040002, 0x30040002, 0x20050002, 0x30050002,
+ 0x20042000, 0x30042000, 0x20052000, 0x30052000,
+ 0x20042002, 0x30042002, 0x20052002, 0x30052002,
+ },
+ {
+ 0x00000000, 0x04000000, 0x00000001, 0x04000001,
+ 0x01000000, 0x05000000, 0x01000001, 0x05000001,
+ 0x00000010, 0x04000010, 0x00000011, 0x04000011,
+ 0x01000010, 0x05000010, 0x01000011, 0x05000011,
+ 0x00080000, 0x04080000, 0x00080001, 0x04080001,
+ 0x01080000, 0x05080000, 0x01080001, 0x05080001,
+ 0x00080010, 0x04080010, 0x00080011, 0x04080011,
+ 0x01080010, 0x05080010, 0x01080011, 0x05080011,
+ 0x00000800, 0x04000800, 0x00000801, 0x04000801,
+ 0x01000800, 0x05000800, 0x01000801, 0x05000801,
+ 0x00000810, 0x04000810, 0x00000811, 0x04000811,
+ 0x01000810, 0x05000810, 0x01000811, 0x05000811,
+ 0x00080800, 0x04080800, 0x00080801, 0x04080801,
+ 0x01080800, 0x05080800, 0x01080801, 0x05080801,
+ 0x00080810, 0x04080810, 0x00080811, 0x04080811,
+ 0x01080810, 0x05080810, 0x01080811, 0x05080811
+ },
+};
+
+
+
+/*
+ * Permute the key to give us our key schedule.
+ */
+int
+mit_des_make_key_sched(mit_des_cblock key, mit_des_key_schedule schedule)
+{
+ register unsigned DES_INT32 c, d;
+
+ {
+ /*
+ * Need a pointer for the keys and a temporary DES_INT32
+ */
+ const unsigned char *k;
+ register unsigned DES_INT32 tmp;
+
+ /*
+ * Fetch the key into something we can work with
+ */
+ k = key;
+
+ /*
+ * The first permutted choice gives us the 28 bits for C0 and
+ * 28 for D0. C0 gets 12 bits from the left key and 16 from
+ * the right, while D0 gets 16 from the left and 12 from the
+ * right. The code knows which bits go where.
+ */
+ tmp = load_32_be(k), k += 4;
+
+ c = PC1_CL[(tmp >> 29) & 0x7]
+ | (PC1_CL[(tmp >> 21) & 0x7] << 1)
+ | (PC1_CL[(tmp >> 13) & 0x7] << 2)
+ | (PC1_CL[(tmp >> 5) & 0x7] << 3);
+ d = PC1_DL[(tmp >> 25) & 0xf]
+ | (PC1_DL[(tmp >> 17) & 0xf] << 1)
+ | (PC1_DL[(tmp >> 9) & 0xf] << 2)
+ | (PC1_DL[(tmp >> 1) & 0xf] << 3);
+
+ tmp = load_32_be(k), k += 4;
+
+ c |= PC1_CR[(tmp >> 28) & 0xf]
+ | (PC1_CR[(tmp >> 20) & 0xf] << 1)
+ | (PC1_CR[(tmp >> 12) & 0xf] << 2)
+ | (PC1_CR[(tmp >> 4) & 0xf] << 3);
+ d |= PC1_DR[(tmp >> 25) & 0x7]
+ | (PC1_DR[(tmp >> 17) & 0x7] << 1)
+ | (PC1_DR[(tmp >> 9) & 0x7] << 2)
+ | (PC1_DR[(tmp >> 1) & 0x7] << 3);
+ }
+
+ {
+ /*
+ * Need several temporaries in here
+ */
+ register unsigned DES_INT32 ltmp, rtmp;
+ register unsigned DES_INT32 *k;
+ register int two_bit_shifts;
+ register int i;
+ /*
+ * Now iterate to compute the key schedule. Note that we
+ * record the entire set of subkeys in 6 bit chunks since
+ * they are used that way. At 6 bits/char, we need
+ * 48/6 char's/subkey * 16 subkeys/encryption == 128 bytes.
+ * The schedule must be this big.
+ */
+ k = (unsigned DES_INT32 *)schedule;
+ two_bit_shifts = TWO_BIT_SHIFTS;
+ for (i = 16; i > 0; i--) {
+ /*
+ * Do the rotation. One bit and two bit rotations
+ * are done separately. Note C and D are 28 bits.
+ */
+ if (two_bit_shifts & 0x1) {
+ c = ((c << 2) & 0xffffffc) | (c >> 26);
+ d = ((d << 2) & 0xffffffc) | (d >> 26);
+ } else {
+ c = ((c << 1) & 0xffffffe) | (c >> 27);
+ d = ((d << 1) & 0xffffffe) | (d >> 27);
+ }
+ two_bit_shifts >>= 1;
+
+ /*
+ * Apply permutted choice 2 to C to get the first
+ * 24 bits worth of keys. Note that bits 9, 18, 22
+ * and 25 (using DES numbering) in C are unused. The
+ * shift-mask stuff is done to delete these bits from
+ * the indices, since this cuts the table size in half.
+ *
+ * The table is torqued, by the way. If the standard
+ * byte order for this (high to low order) is 1234,
+ * the table actually gives us 4132.
+ */
+ ltmp = PC2_C[0][((c >> 22) & 0x3f)]
+ | PC2_C[1][((c >> 15) & 0xf) | ((c >> 16) & 0x30)]
+ | PC2_C[2][((c >> 4) & 0x3) | ((c >> 9) & 0x3c)]
+ | PC2_C[3][((c ) & 0x7) | ((c >> 4) & 0x38)];
+ /*
+ * Apply permutted choice 2 to D to get the other half.
+ * Here, bits 7, 10, 15 and 26 go unused. The sqeezing
+ * actually turns out to be cheaper here.
+ *
+ * This table is similarly torqued. If the standard
+ * byte order is 5678, the table has the bytes permuted
+ * to give us 7685.
+ */
+ rtmp = PC2_D[0][((d >> 22) & 0x3f)]
+ | PC2_D[1][((d >> 14) & 0xf) | ((d >> 15) & 0x30)]
+ | PC2_D[2][((d >> 7) & 0x3f)]
+ | PC2_D[3][((d ) & 0x3) | ((d >> 1) & 0x3c)];
+
+ /*
+ * Make up two words of the key schedule, with a
+ * byte order which is convenient for the DES
+ * inner loop. The high order (first) word will
+ * hold bytes 7135 (high to low order) while the
+ * second holds bytes 4682.
+ */
+ *k++ = (ltmp & 0x00ffff00) | (rtmp & 0xff0000ff);
+ *k++ = (ltmp & 0xff0000ff) | (rtmp & 0x00ffff00);
+ }
+ }
+ return (0);
+}
diff --git a/src/lib/crypto/builtin/des/f_tables.c b/src/lib/crypto/builtin/des/f_tables.c
new file mode 100644
index 000000000000..6308cb0d5cf1
--- /dev/null
+++ b/src/lib/crypto/builtin/des/f_tables.c
@@ -0,0 +1,370 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/f_tables.c */
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/* DES implementation donated by Dennis Ferguson */
+
+/*
+ * des_tables.c - precomputed tables used for the DES cipher function
+ */
+
+/*
+ * Include the header file so something will complain if the
+ * declarations get out of sync
+ */
+#include "des_int.h"
+#include "f_tables.h"
+
+/*
+ * These tables may be declared const if you want. Many compilers
+ * don't support this, though.
+ */
+
+/*
+ * The DES algorithm which uses these is intended to be fairly speedy
+ * at the expense of some memory. All the standard hacks are used.
+ * The S boxes and the P permutation are precomputed into one table.
+ * The E box never actually appears explicitly since it is easy to apply
+ * this algorithmically as needed. The initial permutation and final
+ * (inverse initial) permutation are computed from tables designed to
+ * permute one byte at a time. This should run pretty fast on machines
+ * with 32 bit words and bit field/multiple bit shift instructions which
+ * are fast.
+ */
+
+/*
+ * The initial permutation array. This is used to compute both the
+ * left and the right halves of the initial permutation using bytes
+ * from words made from the following operations:
+ *
+ * ((left & 0x55555555) << 1) | (right & 0x55555555) for left half
+ * (left & 0xaaaaaaaa) | ((right & 0xaaaaaaaa) >> 1) for right half
+ *
+ * The scheme is that we index into the table using each byte. The
+ * result from the high order byte is or'd with the result from the
+ * next byte shifted left once is or'd with the result from the next
+ * byte shifted left twice if or'd with the result from the low order
+ * byte shifted left by three. Clear?
+ */
+
+const unsigned DES_INT32 des_IP_table[256] = {
+ 0x00000000, 0x00000010, 0x00000001, 0x00000011,
+ 0x00001000, 0x00001010, 0x00001001, 0x00001011,
+ 0x00000100, 0x00000110, 0x00000101, 0x00000111,
+ 0x00001100, 0x00001110, 0x00001101, 0x00001111,
+ 0x00100000, 0x00100010, 0x00100001, 0x00100011,
+ 0x00101000, 0x00101010, 0x00101001, 0x00101011,
+ 0x00100100, 0x00100110, 0x00100101, 0x00100111,
+ 0x00101100, 0x00101110, 0x00101101, 0x00101111,
+ 0x00010000, 0x00010010, 0x00010001, 0x00010011,
+ 0x00011000, 0x00011010, 0x00011001, 0x00011011,
+ 0x00010100, 0x00010110, 0x00010101, 0x00010111,
+ 0x00011100, 0x00011110, 0x00011101, 0x00011111,
+ 0x00110000, 0x00110010, 0x00110001, 0x00110011,
+ 0x00111000, 0x00111010, 0x00111001, 0x00111011,
+ 0x00110100, 0x00110110, 0x00110101, 0x00110111,
+ 0x00111100, 0x00111110, 0x00111101, 0x00111111,
+ 0x10000000, 0x10000010, 0x10000001, 0x10000011,
+ 0x10001000, 0x10001010, 0x10001001, 0x10001011,
+ 0x10000100, 0x10000110, 0x10000101, 0x10000111,
+ 0x10001100, 0x10001110, 0x10001101, 0x10001111,
+ 0x10100000, 0x10100010, 0x10100001, 0x10100011,
+ 0x10101000, 0x10101010, 0x10101001, 0x10101011,
+ 0x10100100, 0x10100110, 0x10100101, 0x10100111,
+ 0x10101100, 0x10101110, 0x10101101, 0x10101111,
+ 0x10010000, 0x10010010, 0x10010001, 0x10010011,
+ 0x10011000, 0x10011010, 0x10011001, 0x10011011,
+ 0x10010100, 0x10010110, 0x10010101, 0x10010111,
+ 0x10011100, 0x10011110, 0x10011101, 0x10011111,
+ 0x10110000, 0x10110010, 0x10110001, 0x10110011,
+ 0x10111000, 0x10111010, 0x10111001, 0x10111011,
+ 0x10110100, 0x10110110, 0x10110101, 0x10110111,
+ 0x10111100, 0x10111110, 0x10111101, 0x10111111,
+ 0x01000000, 0x01000010, 0x01000001, 0x01000011,
+ 0x01001000, 0x01001010, 0x01001001, 0x01001011,
+ 0x01000100, 0x01000110, 0x01000101, 0x01000111,
+ 0x01001100, 0x01001110, 0x01001101, 0x01001111,
+ 0x01100000, 0x01100010, 0x01100001, 0x01100011,
+ 0x01101000, 0x01101010, 0x01101001, 0x01101011,
+ 0x01100100, 0x01100110, 0x01100101, 0x01100111,
+ 0x01101100, 0x01101110, 0x01101101, 0x01101111,
+ 0x01010000, 0x01010010, 0x01010001, 0x01010011,
+ 0x01011000, 0x01011010, 0x01011001, 0x01011011,
+ 0x01010100, 0x01010110, 0x01010101, 0x01010111,
+ 0x01011100, 0x01011110, 0x01011101, 0x01011111,
+ 0x01110000, 0x01110010, 0x01110001, 0x01110011,
+ 0x01111000, 0x01111010, 0x01111001, 0x01111011,
+ 0x01110100, 0x01110110, 0x01110101, 0x01110111,
+ 0x01111100, 0x01111110, 0x01111101, 0x01111111,
+ 0x11000000, 0x11000010, 0x11000001, 0x11000011,
+ 0x11001000, 0x11001010, 0x11001001, 0x11001011,
+ 0x11000100, 0x11000110, 0x11000101, 0x11000111,
+ 0x11001100, 0x11001110, 0x11001101, 0x11001111,
+ 0x11100000, 0x11100010, 0x11100001, 0x11100011,
+ 0x11101000, 0x11101010, 0x11101001, 0x11101011,
+ 0x11100100, 0x11100110, 0x11100101, 0x11100111,
+ 0x11101100, 0x11101110, 0x11101101, 0x11101111,
+ 0x11010000, 0x11010010, 0x11010001, 0x11010011,
+ 0x11011000, 0x11011010, 0x11011001, 0x11011011,
+ 0x11010100, 0x11010110, 0x11010101, 0x11010111,
+ 0x11011100, 0x11011110, 0x11011101, 0x11011111,
+ 0x11110000, 0x11110010, 0x11110001, 0x11110011,
+ 0x11111000, 0x11111010, 0x11111001, 0x11111011,
+ 0x11110100, 0x11110110, 0x11110101, 0x11110111,
+ 0x11111100, 0x11111110, 0x11111101, 0x11111111
+};
+
+/*
+ * The final permutation array. Like the IP array, used
+ * to compute both the left and right results from the bytes
+ * of words computed from:
+ *
+ * ((left & 0x0f0f0f0f) << 4) | (right & 0x0f0f0f0f) for left result
+ * (left & 0xf0f0f0f0) | ((right & 0xf0f0f0f0) >> 4) for right result
+ *
+ * The result from the high order byte is shifted left 6 bits and
+ * or'd with the result from the next byte shifted left 4 bits, which
+ * is or'd with the result from the next byte shifted left 2 bits,
+ * which is or'd with the result from the low byte.
+ */
+const unsigned DES_INT32 des_FP_table[256] = {
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000,
+ 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000002, 0x02000002, 0x00020002, 0x02020002,
+ 0x00000202, 0x02000202, 0x00020202, 0x02020202,
+ 0x01000000, 0x03000000, 0x01020000, 0x03020000,
+ 0x01000200, 0x03000200, 0x01020200, 0x03020200,
+ 0x01000002, 0x03000002, 0x01020002, 0x03020002,
+ 0x01000202, 0x03000202, 0x01020202, 0x03020202,
+ 0x00010000, 0x02010000, 0x00030000, 0x02030000,
+ 0x00010200, 0x02010200, 0x00030200, 0x02030200,
+ 0x00010002, 0x02010002, 0x00030002, 0x02030002,
+ 0x00010202, 0x02010202, 0x00030202, 0x02030202,
+ 0x01010000, 0x03010000, 0x01030000, 0x03030000,
+ 0x01010200, 0x03010200, 0x01030200, 0x03030200,
+ 0x01010002, 0x03010002, 0x01030002, 0x03030002,
+ 0x01010202, 0x03010202, 0x01030202, 0x03030202,
+ 0x00000100, 0x02000100, 0x00020100, 0x02020100,
+ 0x00000300, 0x02000300, 0x00020300, 0x02020300,
+ 0x00000102, 0x02000102, 0x00020102, 0x02020102,
+ 0x00000302, 0x02000302, 0x00020302, 0x02020302,
+ 0x01000100, 0x03000100, 0x01020100, 0x03020100,
+ 0x01000300, 0x03000300, 0x01020300, 0x03020300,
+ 0x01000102, 0x03000102, 0x01020102, 0x03020102,
+ 0x01000302, 0x03000302, 0x01020302, 0x03020302,
+ 0x00010100, 0x02010100, 0x00030100, 0x02030100,
+ 0x00010300, 0x02010300, 0x00030300, 0x02030300,
+ 0x00010102, 0x02010102, 0x00030102, 0x02030102,
+ 0x00010302, 0x02010302, 0x00030302, 0x02030302,
+ 0x01010100, 0x03010100, 0x01030100, 0x03030100,
+ 0x01010300, 0x03010300, 0x01030300, 0x03030300,
+ 0x01010102, 0x03010102, 0x01030102, 0x03030102,
+ 0x01010302, 0x03010302, 0x01030302, 0x03030302,
+ 0x00000001, 0x02000001, 0x00020001, 0x02020001,
+ 0x00000201, 0x02000201, 0x00020201, 0x02020201,
+ 0x00000003, 0x02000003, 0x00020003, 0x02020003,
+ 0x00000203, 0x02000203, 0x00020203, 0x02020203,
+ 0x01000001, 0x03000001, 0x01020001, 0x03020001,
+ 0x01000201, 0x03000201, 0x01020201, 0x03020201,
+ 0x01000003, 0x03000003, 0x01020003, 0x03020003,
+ 0x01000203, 0x03000203, 0x01020203, 0x03020203,
+ 0x00010001, 0x02010001, 0x00030001, 0x02030001,
+ 0x00010201, 0x02010201, 0x00030201, 0x02030201,
+ 0x00010003, 0x02010003, 0x00030003, 0x02030003,
+ 0x00010203, 0x02010203, 0x00030203, 0x02030203,
+ 0x01010001, 0x03010001, 0x01030001, 0x03030001,
+ 0x01010201, 0x03010201, 0x01030201, 0x03030201,
+ 0x01010003, 0x03010003, 0x01030003, 0x03030003,
+ 0x01010203, 0x03010203, 0x01030203, 0x03030203,
+ 0x00000101, 0x02000101, 0x00020101, 0x02020101,
+ 0x00000301, 0x02000301, 0x00020301, 0x02020301,
+ 0x00000103, 0x02000103, 0x00020103, 0x02020103,
+ 0x00000303, 0x02000303, 0x00020303, 0x02020303,
+ 0x01000101, 0x03000101, 0x01020101, 0x03020101,
+ 0x01000301, 0x03000301, 0x01020301, 0x03020301,
+ 0x01000103, 0x03000103, 0x01020103, 0x03020103,
+ 0x01000303, 0x03000303, 0x01020303, 0x03020303,
+ 0x00010101, 0x02010101, 0x00030101, 0x02030101,
+ 0x00010301, 0x02010301, 0x00030301, 0x02030301,
+ 0x00010103, 0x02010103, 0x00030103, 0x02030103,
+ 0x00010303, 0x02010303, 0x00030303, 0x02030303,
+ 0x01010101, 0x03010101, 0x01030101, 0x03030101,
+ 0x01010301, 0x03010301, 0x01030301, 0x03030301,
+ 0x01010103, 0x03010103, 0x01030103, 0x03030103,
+ 0x01010303, 0x03010303, 0x01030303, 0x03030303
+};
+
+
+/*
+ * The SP table is actually the S boxes and the P permutation
+ * table combined. This table is actually reordered from the
+ * spec, to match the order of key application we follow.
+ */
+const unsigned DES_INT32 des_SP_table[8][64] = {
+ {
+ 0x00100000, 0x02100001, 0x02000401, 0x00000000, /* 7 */
+ 0x00000400, 0x02000401, 0x00100401, 0x02100400,
+ 0x02100401, 0x00100000, 0x00000000, 0x02000001,
+ 0x00000001, 0x02000000, 0x02100001, 0x00000401,
+ 0x02000400, 0x00100401, 0x00100001, 0x02000400,
+ 0x02000001, 0x02100000, 0x02100400, 0x00100001,
+ 0x02100000, 0x00000400, 0x00000401, 0x02100401,
+ 0x00100400, 0x00000001, 0x02000000, 0x00100400,
+ 0x02000000, 0x00100400, 0x00100000, 0x02000401,
+ 0x02000401, 0x02100001, 0x02100001, 0x00000001,
+ 0x00100001, 0x02000000, 0x02000400, 0x00100000,
+ 0x02100400, 0x00000401, 0x00100401, 0x02100400,
+ 0x00000401, 0x02000001, 0x02100401, 0x02100000,
+ 0x00100400, 0x00000000, 0x00000001, 0x02100401,
+ 0x00000000, 0x00100401, 0x02100000, 0x00000400,
+ 0x02000001, 0x02000400, 0x00000400, 0x00100001,
+ },
+ {
+ 0x00808200, 0x00000000, 0x00008000, 0x00808202, /* 1 */
+ 0x00808002, 0x00008202, 0x00000002, 0x00008000,
+ 0x00000200, 0x00808200, 0x00808202, 0x00000200,
+ 0x00800202, 0x00808002, 0x00800000, 0x00000002,
+ 0x00000202, 0x00800200, 0x00800200, 0x00008200,
+ 0x00008200, 0x00808000, 0x00808000, 0x00800202,
+ 0x00008002, 0x00800002, 0x00800002, 0x00008002,
+ 0x00000000, 0x00000202, 0x00008202, 0x00800000,
+ 0x00008000, 0x00808202, 0x00000002, 0x00808000,
+ 0x00808200, 0x00800000, 0x00800000, 0x00000200,
+ 0x00808002, 0x00008000, 0x00008200, 0x00800002,
+ 0x00000200, 0x00000002, 0x00800202, 0x00008202,
+ 0x00808202, 0x00008002, 0x00808000, 0x00800202,
+ 0x00800002, 0x00000202, 0x00008202, 0x00808200,
+ 0x00000202, 0x00800200, 0x00800200, 0x00000000,
+ 0x00008002, 0x00008200, 0x00000000, 0x00808002,
+ },
+ {
+ 0x00000104, 0x04010100, 0x00000000, 0x04010004, /* 3 */
+ 0x04000100, 0x00000000, 0x00010104, 0x04000100,
+ 0x00010004, 0x04000004, 0x04000004, 0x00010000,
+ 0x04010104, 0x00010004, 0x04010000, 0x00000104,
+ 0x04000000, 0x00000004, 0x04010100, 0x00000100,
+ 0x00010100, 0x04010000, 0x04010004, 0x00010104,
+ 0x04000104, 0x00010100, 0x00010000, 0x04000104,
+ 0x00000004, 0x04010104, 0x00000100, 0x04000000,
+ 0x04010100, 0x04000000, 0x00010004, 0x00000104,
+ 0x00010000, 0x04010100, 0x04000100, 0x00000000,
+ 0x00000100, 0x00010004, 0x04010104, 0x04000100,
+ 0x04000004, 0x00000100, 0x00000000, 0x04010004,
+ 0x04000104, 0x00010000, 0x04000000, 0x04010104,
+ 0x00000004, 0x00010104, 0x00010100, 0x04000004,
+ 0x04010000, 0x04000104, 0x00000104, 0x04010000,
+ 0x00010104, 0x00000004, 0x04010004, 0x00010100,
+ },
+ {
+ 0x00000080, 0x01040080, 0x01040000, 0x21000080, /* 5 */
+ 0x00040000, 0x00000080, 0x20000000, 0x01040000,
+ 0x20040080, 0x00040000, 0x01000080, 0x20040080,
+ 0x21000080, 0x21040000, 0x00040080, 0x20000000,
+ 0x01000000, 0x20040000, 0x20040000, 0x00000000,
+ 0x20000080, 0x21040080, 0x21040080, 0x01000080,
+ 0x21040000, 0x20000080, 0x00000000, 0x21000000,
+ 0x01040080, 0x01000000, 0x21000000, 0x00040080,
+ 0x00040000, 0x21000080, 0x00000080, 0x01000000,
+ 0x20000000, 0x01040000, 0x21000080, 0x20040080,
+ 0x01000080, 0x20000000, 0x21040000, 0x01040080,
+ 0x20040080, 0x00000080, 0x01000000, 0x21040000,
+ 0x21040080, 0x00040080, 0x21000000, 0x21040080,
+ 0x01040000, 0x00000000, 0x20040000, 0x21000000,
+ 0x00040080, 0x01000080, 0x20000080, 0x00040000,
+ 0x00000000, 0x20040000, 0x01040080, 0x20000080,
+ },
+ {
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040, /* 4 */
+ 0x00401040, 0x80400040, 0x80400000, 0x80001000,
+ 0x00000000, 0x00401000, 0x00401000, 0x80401040,
+ 0x80000040, 0x00000000, 0x00400040, 0x80400000,
+ 0x80000000, 0x00001000, 0x00400000, 0x80401000,
+ 0x00000040, 0x00400000, 0x80001000, 0x00001040,
+ 0x80400040, 0x80000000, 0x00001040, 0x00400040,
+ 0x00001000, 0x00401040, 0x80401040, 0x80000040,
+ 0x00400040, 0x80400000, 0x00401000, 0x80401040,
+ 0x80000040, 0x00000000, 0x00000000, 0x00401000,
+ 0x00001040, 0x00400040, 0x80400040, 0x80000000,
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040,
+ 0x80401040, 0x80000040, 0x80000000, 0x00001000,
+ 0x80400000, 0x80001000, 0x00401040, 0x80400040,
+ 0x80001000, 0x00001040, 0x00400000, 0x80401000,
+ 0x00000040, 0x00400000, 0x00001000, 0x00401040,
+ },
+ {
+ 0x10000008, 0x10200000, 0x00002000, 0x10202008, /* 6 */
+ 0x10200000, 0x00000008, 0x10202008, 0x00200000,
+ 0x10002000, 0x00202008, 0x00200000, 0x10000008,
+ 0x00200008, 0x10002000, 0x10000000, 0x00002008,
+ 0x00000000, 0x00200008, 0x10002008, 0x00002000,
+ 0x00202000, 0x10002008, 0x00000008, 0x10200008,
+ 0x10200008, 0x00000000, 0x00202008, 0x10202000,
+ 0x00002008, 0x00202000, 0x10202000, 0x10000000,
+ 0x10002000, 0x00000008, 0x10200008, 0x00202000,
+ 0x10202008, 0x00200000, 0x00002008, 0x10000008,
+ 0x00200000, 0x10002000, 0x10000000, 0x00002008,
+ 0x10000008, 0x10202008, 0x00202000, 0x10200000,
+ 0x00202008, 0x10202000, 0x00000000, 0x10200008,
+ 0x00000008, 0x00002000, 0x10200000, 0x00202008,
+ 0x00002000, 0x00200008, 0x10002008, 0x00000000,
+ 0x10202000, 0x10000000, 0x00200008, 0x10002008,
+ },
+ {
+ 0x08000820, 0x00000800, 0x00020000, 0x08020820, /* 8 */
+ 0x08000000, 0x08000820, 0x00000020, 0x08000000,
+ 0x00020020, 0x08020000, 0x08020820, 0x00020800,
+ 0x08020800, 0x00020820, 0x00000800, 0x00000020,
+ 0x08020000, 0x08000020, 0x08000800, 0x00000820,
+ 0x00020800, 0x00020020, 0x08020020, 0x08020800,
+ 0x00000820, 0x00000000, 0x00000000, 0x08020020,
+ 0x08000020, 0x08000800, 0x00020820, 0x00020000,
+ 0x00020820, 0x00020000, 0x08020800, 0x00000800,
+ 0x00000020, 0x08020020, 0x00000800, 0x00020820,
+ 0x08000800, 0x00000020, 0x08000020, 0x08020000,
+ 0x08020020, 0x08000000, 0x00020000, 0x08000820,
+ 0x00000000, 0x08020820, 0x00020020, 0x08000020,
+ 0x08020000, 0x08000800, 0x08000820, 0x00000000,
+ 0x08020820, 0x00020800, 0x00020800, 0x00000820,
+ 0x00000820, 0x00020020, 0x08000000, 0x08020800,
+ },
+ {
+ 0x40084010, 0x40004000, 0x00004000, 0x00084010, /* 2 */
+ 0x00080000, 0x00000010, 0x40080010, 0x40004010,
+ 0x40000010, 0x40084010, 0x40084000, 0x40000000,
+ 0x40004000, 0x00080000, 0x00000010, 0x40080010,
+ 0x00084000, 0x00080010, 0x40004010, 0x00000000,
+ 0x40000000, 0x00004000, 0x00084010, 0x40080000,
+ 0x00080010, 0x40000010, 0x00000000, 0x00084000,
+ 0x00004010, 0x40084000, 0x40080000, 0x00004010,
+ 0x00000000, 0x00084010, 0x40080010, 0x00080000,
+ 0x40004010, 0x40080000, 0x40084000, 0x00004000,
+ 0x40080000, 0x40004000, 0x00000010, 0x40084010,
+ 0x00084010, 0x00000010, 0x00004000, 0x40000000,
+ 0x00004010, 0x40084000, 0x00080000, 0x40000010,
+ 0x00080010, 0x40004010, 0x40000010, 0x00080010,
+ 0x00084000, 0x00000000, 0x40004000, 0x00004010,
+ 0x40000000, 0x40080010, 0x40084010, 0x00084000
+ },
+};
diff --git a/src/lib/crypto/builtin/des/f_tables.h b/src/lib/crypto/builtin/des/f_tables.h
new file mode 100644
index 000000000000..a99eb0a14c6a
--- /dev/null
+++ b/src/lib/crypto/builtin/des/f_tables.h
@@ -0,0 +1,285 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/f_tables.h */
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * DES implementation donated by Dennis Ferguson
+ */
+
+/*
+ * des_tables.h - declarations to import the DES tables, used internally
+ * by some of the library routines.
+ */
+#ifndef __DES_TABLES_H__
+#define __DES_TABLES_H__ /* nothing */
+
+#include "k5-platform.h"
+/*
+ * These may be declared const if you wish. Be sure to change the
+ * declarations in des_tables.c as well.
+ */
+extern const unsigned DES_INT32 des_IP_table[256];
+extern const unsigned DES_INT32 des_FP_table[256];
+extern const unsigned DES_INT32 des_SP_table[8][64];
+
+/*
+ * Use standard shortforms to reference these to save typing
+ */
+#define IP des_IP_table
+#define FP des_FP_table
+#define SP des_SP_table
+
+#ifdef DEBUG
+#define DEB(foofraw) printf foofraw
+#else
+#define DEB(foofraw) /* nothing */
+#endif
+
+/*
+ * Code to do a DES round using the tables. Note that the E expansion
+ * is easy to compute algorithmically, especially if done out-of-order.
+ * Take a look at its form and compare it to everything involving temp
+ * below. Since SP[0-7] don't have any bits in common set it is okay
+ * to do the successive xor's.
+ *
+ * Note too that the SP table has been reordered to match the order of
+ * the keys (if the original order of SP was 12345678, the reordered
+ * table is 71354682). This is unnecessary, but was done since some
+ * compilers seem to like you going through the matrix from beginning
+ * to end.
+ *
+ * There is a difference in the best way to do this depending on whether
+ * one is encrypting or decrypting. If encrypting we move forward through
+ * the keys and hence should move forward through the table. If decrypting
+ * we go back. Part of the need for this comes from trying to emulate
+ * existing software which generates a single key schedule and uses it
+ * both for encrypting and decrypting. Generating separate encryption
+ * and decryption key schedules would allow one to use the same code
+ * for both.
+ *
+ * left, right and temp should be unsigned DES_INT32 values. left and right
+ * should be the high and low order parts of the cipher block at the
+ * current stage of processing (this makes sense if you read the spec).
+ * kp should be an unsigned DES_INT32 pointer which points at the current
+ * set of subkeys in the key schedule. It is advanced to the next set
+ * (i.e. by 8 bytes) when this is done.
+ *
+ * This occurs in the innermost loop of the DES function. The four
+ * variables should really be in registers.
+ *
+ * When using this, the inner loop of the DES function might look like:
+ *
+ * for (i = 0; i < 8; i++) {
+ * DES_SP_{EN,DE}CRYPT_ROUND(left, right, temp, kp);
+ * DES_SP_{EN,DE}CRYPT_ROUND(right, left, temp, kp);
+ * }
+ *
+ * Note the trick above. You are supposed to do 16 rounds, swapping
+ * left and right at the end of each round. By doing two rounds at
+ * a time and swapping left and right in the code we can avoid the
+ * swaps altogether.
+ */
+#define DES_SP_ENCRYPT_ROUND(left, right, temp, kp) do { \
+ (temp) = (((right) >> 11) | ((right) << 21)) ^ *(kp)++; \
+ (left) ^= SP[0][((temp) >> 24) & 0x3f] \
+ | SP[1][((temp) >> 16) & 0x3f] \
+ | SP[2][((temp) >> 8) & 0x3f] \
+ | SP[3][((temp) ) & 0x3f]; \
+ (temp) = (((right) >> 23) | ((right) << 9)) ^ *(kp)++; \
+ (left) ^= SP[4][((temp) >> 24) & 0x3f] \
+ | SP[5][((temp) >> 16) & 0x3f] \
+ | SP[6][((temp) >> 8) & 0x3f] \
+ | SP[7][((temp) ) & 0x3f]; \
+ } while(0);
+
+#define DES_SP_DECRYPT_ROUND(left, right, temp, kp) do { \
+ (temp) = (((right) >> 23) | ((right) << 9)) ^ *(--(kp)); \
+ (left) ^= SP[7][((temp) ) & 0x3f] \
+ | SP[6][((temp) >> 8) & 0x3f] \
+ | SP[5][((temp) >> 16) & 0x3f] \
+ | SP[4][((temp) >> 24) & 0x3f]; \
+ (temp) = (((right) >> 11) | ((right) << 21)) ^ *(--(kp)); \
+ (left) ^= SP[3][((temp) ) & 0x3f] \
+ | SP[2][((temp) >> 8) & 0x3f] \
+ | SP[1][((temp) >> 16) & 0x3f] \
+ | SP[0][((temp) >> 24) & 0x3f]; \
+ } while (0);
+
+/*
+ * Macros to help deal with the initial permutation table. Note
+ * the IP table only deals with 32 bits at a time, allowing us to
+ * collect the bits we need to deal with each half into an unsigned
+ * DES_INT32. By carefully selecting how the bits are ordered we also
+ * take advantages of symmetries in the table so that we can use a
+ * single table to compute the permutation of all bytes. This sounds
+ * complicated, but if you go through the process of designing the
+ * table you'll find the symmetries fall right out.
+ *
+ * The follow macros compute the set of bits used to index the
+ * table for produce the left and right permuted result.
+ *
+ * The inserted cast to unsigned DES_INT32 circumvents a bug in
+ * the Macintosh MPW 3.2 C compiler which loses the unsignedness and
+ * propagates the high-order bit in the shift.
+ */
+#define DES_IP_LEFT_BITS(left, right) \
+ ((((left) & 0x55555555) << 1) | ((right) & 0x55555555))
+#define DES_IP_RIGHT_BITS(left, right) \
+ (((left) & 0xaaaaaaaa) | \
+ ( ( (unsigned DES_INT32) ((right) & 0xaaaaaaaa) ) >> 1))
+
+/*
+ * The following macro does an in-place initial permutation given
+ * the current left and right parts of the block and a single
+ * temporary. Use this more as a guide for rolling your own, though.
+ * The best way to do the IP depends on the form of the data you
+ * are dealing with. If you use this, though, try to make left,
+ * right and temp register unsigned DES_INT32s.
+ */
+#define DES_INITIAL_PERM(left, right, temp) do { \
+ (temp) = DES_IP_RIGHT_BITS((left), (right)); \
+ (right) = DES_IP_LEFT_BITS((left), (right)); \
+ (left) = IP[((right) >> 24) & 0xff] \
+ | (IP[((right) >> 16) & 0xff] << 1) \
+ | (IP[((right) >> 8) & 0xff] << 2) \
+ | (IP[(right) & 0xff] << 3); \
+ (right) = IP[((temp) >> 24) & 0xff] \
+ | (IP[((temp) >> 16) & 0xff] << 1) \
+ | (IP[((temp) >> 8) & 0xff] << 2) \
+ | (IP[(temp) & 0xff] << 3); \
+ } while(0);
+
+/*
+ * Now the final permutation stuff. The same comments apply to
+ * this as to the initial permutation, except that we use different
+ * bits and shifts.
+ *
+ * The inserted cast to unsigned DES_INT32 circumvents a bug in
+ * the Macintosh MPW 3.2 C compiler which loses the unsignedness and
+ * propagates the high-order bit in the shift.
+ */
+#define DES_FP_LEFT_BITS(left, right) \
+ ((((left) & 0x0f0f0f0f) << 4) | ((right) & 0x0f0f0f0f))
+#define DES_FP_RIGHT_BITS(left, right) \
+ (((left) & 0xf0f0f0f0) | \
+ ( ( (unsigned DES_INT32) ((right) & 0xf0f0f0f0) ) >> 4))
+
+
+/*
+ * Here is a sample final permutation. Note that there is a trick
+ * here. DES requires swapping the left and right parts after the
+ * last cipher round but before the final permutation. We do this
+ * swapping internally, which is why left and right are confused
+ * at the beginning.
+ */
+#define DES_FINAL_PERM(left, right, temp) do { \
+ (temp) = DES_FP_RIGHT_BITS((right), (left)); \
+ (right) = DES_FP_LEFT_BITS((right), (left)); \
+ (left) = (FP[((right) >> 24) & 0xff] << 6) \
+ | (FP[((right) >> 16) & 0xff] << 4) \
+ | (FP[((right) >> 8) & 0xff] << 2) \
+ | FP[(right) & 0xff]; \
+ (right) = (FP[((temp) >> 24) & 0xff] << 6) \
+ | (FP[((temp) >> 16) & 0xff] << 4) \
+ | (FP[((temp) >> 8) & 0xff] << 2) \
+ | FP[temp & 0xff]; \
+ } while(0);
+
+
+/*
+ * Finally, as a sample of how all this might be held together, the
+ * following two macros do in-place encryptions and decryptions. left
+ * and right are two unsigned DES_INT32 variables which at the beginning
+ * are expected to hold the clear (encrypted) block in host byte order
+ * (left the high order four bytes, right the low order). At the end
+ * they will contain the encrypted (clear) block. temp is an unsigned DES_INT32
+ * used as a temporary. kp is an unsigned DES_INT32 pointer pointing at
+ * the start of the key schedule. All these should be in registers.
+ *
+ * You can probably do better than these by rewriting for particular
+ * situations. These aren't bad, though.
+ *
+ * The DEB macros enable debugging when this code breaks (typically
+ * when a buggy compiler breaks it), by printing the intermediate values
+ * at each stage of the encryption, so that by comparing the output to
+ * a known good machine, the location of the first error can be found.
+ */
+#define DES_DO_ENCRYPT_1(left, right, kp) \
+ do { \
+ register int i; \
+ register unsigned DES_INT32 temp1; \
+ DEB (("do_encrypt %8lX %8lX \n", left, right)); \
+ DES_INITIAL_PERM((left), (right), (temp1)); \
+ DEB ((" after IP %8lX %8lX\n", left, right)); \
+ for (i = 0; i < 8; i++) { \
+ DES_SP_ENCRYPT_ROUND((left), (right), (temp1), (kp)); \
+ DEB ((" round %2d %8lX %8lX \n", i*2, left, right)); \
+ DES_SP_ENCRYPT_ROUND((right), (left), (temp1), (kp)); \
+ DEB ((" round %2d %8lX %8lX \n", 1+i*2, left, right)); \
+ } \
+ DES_FINAL_PERM((left), (right), (temp1)); \
+ (kp) -= (2 * 16); \
+ DEB ((" after FP %8lX %8lX \n", left, right)); \
+ } while (0)
+
+#define DES_DO_DECRYPT_1(left, right, kp) \
+ do { \
+ register int i; \
+ register unsigned DES_INT32 temp2; \
+ DES_INITIAL_PERM((left), (right), (temp2)); \
+ (kp) += (2 * 16); \
+ for (i = 0; i < 8; i++) { \
+ DES_SP_DECRYPT_ROUND((left), (right), (temp2), (kp)); \
+ DES_SP_DECRYPT_ROUND((right), (left), (temp2), (kp)); \
+ } \
+ DES_FINAL_PERM((left), (right), (temp2)); \
+ } while (0)
+
+#if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
+extern void krb5int_des_do_encrypt_2(unsigned DES_INT32 *l,
+ unsigned DES_INT32 *r,
+ const unsigned DES_INT32 *k);
+extern void krb5int_des_do_decrypt_2(unsigned DES_INT32 *l,
+ unsigned DES_INT32 *r,
+ const unsigned DES_INT32 *k);
+#define DES_DO_ENCRYPT(L,R,K) krb5int_des_do_encrypt_2(&(L), &(R), (K))
+#define DES_DO_DECRYPT(L,R,K) krb5int_des_do_decrypt_2(&(L), &(R), (K))
+#else
+#define DES_DO_ENCRYPT DES_DO_ENCRYPT_1
+#define DES_DO_DECRYPT DES_DO_DECRYPT_1
+#endif
+
+/*
+ * These are handy dandy utility thingies for straightening out bytes.
+ * Included here because they're used a couple of places.
+ */
+#define GET_HALF_BLOCK(lr, ip) ((lr) = load_32_be(ip), (ip) += 4)
+#define PUT_HALF_BLOCK(lr, op) (store_32_be(lr, op), (op) += 4)
+
+/* Shorthand that we'll need in several places, for creating values that
+ really can hold 32 bits regardless of the prevailing int size. */
+#define FF_UINT32 ((unsigned DES_INT32) 0xFF)
+
+#endif /* __DES_TABLES_H__ */
diff --git a/src/lib/crypto/builtin/des/key_sched.c b/src/lib/crypto/builtin/des/key_sched.c
new file mode 100644
index 000000000000..87f02b6a9856
--- /dev/null
+++ b/src/lib/crypto/builtin/des/key_sched.c
@@ -0,0 +1,62 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/key_sched.c */
+/*
+ * Copyright 1985, 1986, 1987, 1988, 1990 by the Massachusetts Institute
+ * of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * This routine computes the DES key schedule given a key. The
+ * permutations and shifts have been done at compile time, resulting
+ * in a direct one-step mapping from the input key to the key
+ * schedule.
+ *
+ * Also checks parity and weak keys.
+ *
+ * Watch out for the subscripts -- most effectively start at 1 instead
+ * of at zero. Maybe some bugs in that area.
+ *
+ * In case the user wants to cache the computed key schedule, it is
+ * passed as an arg. Also implies that caller has explicit control
+ * over zeroing both the key schedule and the key.
+ *
+ * Originally written 6/85 by Steve Miller, MIT Project Athena.
+ */
+
+#include "k5-int.h"
+#include "des_int.h"
+
+int
+mit_des_key_sched(mit_des_cblock k, mit_des_key_schedule schedule)
+{
+ mit_des_make_key_sched(k,schedule);
+
+ if (!mit_des_check_key_parity(k)) /* bad parity --> return -1 */
+ return(-1);
+
+ if (mit_des_is_weak_key(k))
+ return(-2);
+
+ /* if key was good, return 0 */
+ return 0;
+}
diff --git a/src/lib/crypto/builtin/des/keytest.data b/src/lib/crypto/builtin/des/keytest.data
new file mode 100644
index 000000000000..7ff34eedcf9d
--- /dev/null
+++ b/src/lib/crypto/builtin/des/keytest.data
@@ -0,0 +1,171 @@
+0101010101010101 95F8A5E5DD31D900 8000000000000000
+0101010101010101 DD7F121CA5015619 4000000000000000
+0101010101010101 2E8653104F3834EA 2000000000000000
+0101010101010101 4BD388FF6CD81D4F 1000000000000000
+0101010101010101 20B9E767B2FB1456 0800000000000000
+0101010101010101 55579380D77138EF 0400000000000000
+0101010101010101 6CC5DEFAAF04512F 0200000000000000
+0101010101010101 0D9F279BA5D87260 0100000000000000
+0101010101010101 D9031B0271BD5A0A 0080000000000000
+0101010101010101 424250B37C3DD951 0040000000000000
+0101010101010101 B8061B7ECD9A21E5 0020000000000000
+0101010101010101 F15D0F286B65BD28 0010000000000000
+0101010101010101 ADD0CC8D6E5DEBA1 0008000000000000
+0101010101010101 E6D5F82752AD63D1 0004000000000000
+0101010101010101 ECBFE3BD3F591A5E 0002000000000000
+0101010101010101 F356834379D165CD 0001000000000000
+0101010101010101 2B9F982F20037FA9 0000800000000000
+0101010101010101 889DE068A16F0BE6 0000400000000000
+0101010101010101 E19E275D846A1298 0000200000000000
+0101010101010101 329A8ED523D71AEC 0000100000000000
+0101010101010101 E7FCE22557D23C97 0000080000000000
+0101010101010101 12A9F5817FF2D65D 0000040000000000
+0101010101010101 A484C3AD38DC9C19 0000020000000000
+0101010101010101 FBE00A8A1EF8AD72 0000010000000000
+0101010101010101 750D079407521363 0000008000000000
+0101010101010101 64FEED9C724C2FAF 0000004000000000
+0101010101010101 F02B263B328E2B60 0000002000000000
+0101010101010101 9D64555A9A10B852 0000001000000000
+0101010101010101 D106FF0BED5255D7 0000000800000000
+0101010101010101 E1652C6B138C64A5 0000000400000000
+0101010101010101 E428581186EC8F46 0000000200000000
+0101010101010101 AEB5F5EDE22D1A36 0000000100000000
+0101010101010101 E943D7568AEC0C5C 0000000080000000
+0101010101010101 DF98C8276F54B04B 0000000040000000
+0101010101010101 B160E4680F6C696F 0000000020000000
+0101010101010101 FA0752B07D9C4AB8 0000000010000000
+0101010101010101 CA3A2B036DBC8502 0000000008000000
+0101010101010101 5E0905517BB59BCF 0000000004000000
+0101010101010101 814EEB3B91D90726 0000000002000000
+0101010101010101 4D49DB1532919C9F 0000000001000000
+0101010101010101 25EB5FC3F8CF0621 0000000000800000
+0101010101010101 AB6A20C0620D1C6F 0000000000400000
+0101010101010101 79E90DBC98F92CCA 0000000000200000
+0101010101010101 866ECEDD8072BB0E 0000000000100000
+0101010101010101 8B54536F2F3E64A8 0000000000080000
+0101010101010101 EA51D3975595B86B 0000000000040000
+0101010101010101 CAFFC6AC4542DE31 0000000000020000
+0101010101010101 8DD45A2DDF90796C 0000000000010000
+0101010101010101 1029D55E880EC2D0 0000000000008000
+0101010101010101 5D86CB23639DBEA9 0000000000004000
+0101010101010101 1D1CA853AE7C0C5F 0000000000002000
+0101010101010101 CE332329248F3228 0000000000001000
+0101010101010101 8405D1ABE24FB942 0000000000000800
+0101010101010101 E643D78090CA4207 0000000000000400
+0101010101010101 48221B9937748A23 0000000000000200
+0101010101010101 DD7C0BBD61FAFD54 0000000000000100
+0101010101010101 2FBC291A570DB5C4 0000000000000080
+0101010101010101 E07C30D7E4E26E12 0000000000000040
+0101010101010101 0953E2258E8E90A1 0000000000000020
+0101010101010101 5B711BC4CEEBF2EE 0000000000000010
+0101010101010101 CC083F1E6D9E85F6 0000000000000008
+0101010101010101 D2FD8867D50D2DFE 0000000000000004
+0101010101010101 06E7EA22CE92708F 0000000000000002
+0101010101010101 166B40B44ABA4BD6 0000000000000001
+8001010101010101 0000000000000000 95A8D72813DAA94D
+4001010101010101 0000000000000000 0EEC1487DD8C26D5
+2001010101010101 0000000000000000 7AD16FFB79C45926
+1001010101010101 0000000000000000 D3746294CA6A6CF3
+0801010101010101 0000000000000000 809F5F873C1FD761
+0401010101010101 0000000000000000 C02FAFFEC989D1FC
+0201010101010101 0000000000000000 4615AA1D33E72F10
+0180010101010101 0000000000000000 2055123350C00858
+0140010101010101 0000000000000000 DF3B99D6577397C8
+0120010101010101 0000000000000000 31FE17369B5288C9
+0110010101010101 0000000000000000 DFDD3CC64DAE1642
+0108010101010101 0000000000000000 178C83CE2B399D94
+0104010101010101 0000000000000000 50F636324A9B7F80
+0102010101010101 0000000000000000 A8468EE3BC18F06D
+0101800101010101 0000000000000000 A2DC9E92FD3CDE92
+0101400101010101 0000000000000000 CAC09F797D031287
+0101200101010101 0000000000000000 90BA680B22AEB525
+0101100101010101 0000000000000000 CE7A24F350E280B6
+0101080101010101 0000000000000000 882BFF0AA01A0B87
+0101040101010101 0000000000000000 25610288924511C2
+0101020101010101 0000000000000000 C71516C29C75D170
+0101018001010101 0000000000000000 5199C29A52C9F059
+0101014001010101 0000000000000000 C22F0A294A71F29F
+0101012001010101 0000000000000000 EE371483714C02EA
+0101011001010101 0000000000000000 A81FBD448F9E522F
+0101010801010101 0000000000000000 4F644C92E192DFED
+0101010401010101 0000000000000000 1AFA9A66A6DF92AE
+0101010201010101 0000000000000000 B3C1CC715CB879D8
+0101010180010101 0000000000000000 19D032E64AB0BD8B
+0101010140010101 0000000000000000 3CFAA7A7DC8720DC
+0101010120010101 0000000000000000 B7265F7F447AC6F3
+0101010110010101 0000000000000000 9DB73B3C0D163F54
+0101010108010101 0000000000000000 8181B65BABF4A975
+0101010104010101 0000000000000000 93C9B64042EAA240
+0101010102010101 0000000000000000 5570530829705592
+0101010101800101 0000000000000000 8638809E878787A0
+0101010101400101 0000000000000000 41B9A79AF79AC208
+0101010101200101 0000000000000000 7A9BE42F2009A892
+0101010101100101 0000000000000000 29038D56BA6D2745
+0101010101080101 0000000000000000 5495C6ABF1E5DF51
+0101010101040101 0000000000000000 AE13DBD561488933
+0101010101020101 0000000000000000 024D1FFA8904E389
+0101010101018001 0000000000000000 D1399712F99BF02E
+0101010101014001 0000000000000000 14C1D7C1CFFEC79E
+0101010101012001 0000000000000000 1DE5279DAE3BED6F
+0101010101011001 0000000000000000 E941A33F85501303
+0101010101010801 0000000000000000 DA99DBBC9A03F379
+0101010101010401 0000000000000000 B7FC92F91D8E92E9
+0101010101010201 0000000000000000 AE8E5CAA3CA04E85
+0101010101010180 0000000000000000 9CC62DF43B6EED74
+0101010101010140 0000000000000000 D863DBB5C59A91A0
+0101010101010120 0000000000000000 A1AB2190545B91D7
+0101010101010110 0000000000000000 0875041E64C570F7
+0101010101010108 0000000000000000 5A594528BEBEF1CC
+0101010101010104 0000000000000000 FCDB3291DE21F0C0
+0101010101010102 0000000000000000 869EFD7F9F265A09
+1046913489980131 0000000000000000 88D55E54F54C97B4
+1007103489988020 0000000000000000 0C0CC00C83EA48FD
+10071034C8980120 0000000000000000 83BC8EF3A6570183
+1046103489988020 0000000000000000 DF725DCAD94EA2E9
+1086911519190101 0000000000000000 E652B53B550BE8B0
+1086911519580101 0000000000000000 AF527120C485CBB0
+5107B01519580101 0000000000000000 0F04CE393DB926D5
+1007B01519190101 0000000000000000 C9F00FFC74079067
+3107915498080101 0000000000000000 7CFD82A593252B4E
+3107919498080101 0000000000000000 CB49A2F9E91363E3
+10079115B9080140 0000000000000000 00B588BE70D23F56
+3107911598080140 0000000000000000 406A9A6AB43399AE
+1007D01589980101 0000000000000000 6CB773611DCA9ADA
+9107911589980101 0000000000000000 67FD21C17DBB5D70
+9107D01589190101 0000000000000000 9592CB4110430787
+1007D01598980120 0000000000000000 A6B7FF68A318DDD3
+1007940498190101 0000000000000000 4D102196C914CA16
+0107910491190401 0000000000000000 2DFA9F4573594965
+0107910491190101 0000000000000000 B46604816C0E0774
+0107940491190401 0000000000000000 6E7E6221A4F34E87
+19079210981A0101 0000000000000000 AA85E74643233199
+1007911998190801 0000000000000000 2E5A19DB4D1962D6
+10079119981A0801 0000000000000000 23A866A809D30894
+1007921098190101 0000000000000000 D812D961F017D320
+100791159819010B 0000000000000000 055605816E58608F
+1004801598190101 0000000000000000 ABD88E8B1B7716F1
+1004801598190102 0000000000000000 537AC95BE69DA1E1
+1004801598190108 0000000000000000 AED0F6AE3C25CDD8
+1002911598100104 0000000000000000 B3E35A5EE53E7B8D
+1002911598190104 0000000000000000 61C79C71921A2EF8
+1002911598100201 0000000000000000 E2F5728F0995013C
+1002911698100101 0000000000000000 1AEAC39A61F0A464
+7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B
+0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271
+07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A
+3849674C2602319E 51454B582DDF440A 7178876E01F19B2A
+04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095
+0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B
+0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09
+43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A
+07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F
+04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088
+37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77
+1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A
+584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56
+025816164629B007 480D39006EE762F2 A1F9915541020B56
+49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556
+4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC
+49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A
+018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41
+1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
diff --git a/src/lib/crypto/builtin/des/t_verify.c b/src/lib/crypto/builtin/des/t_verify.c
new file mode 100644
index 000000000000..1f3239fed681
--- /dev/null
+++ b/src/lib/crypto/builtin/des/t_verify.c
@@ -0,0 +1,419 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/t_verify.c */
+/*
+ * Copyright 1988, 1990 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *
+ * Program to test the correctness of the DES library
+ * implementation.
+ *
+ * exit returns 0 ==> success
+ * -1 ==> error
+ */
+
+#include "k5-int.h"
+#include "des_int.h"
+#include <stdio.h>
+#include "com_err.h"
+
+static void do_encrypt(unsigned char *, unsigned char *);
+static void do_decrypt(unsigned char *, unsigned char *);
+
+char *progname;
+int nflag = 2;
+int vflag;
+int mflag;
+int zflag;
+int pid;
+int mit_des_debug;
+
+unsigned char cipher_text[64];
+unsigned char clear_text[64] = "Now is the time for all " ;
+unsigned char clear_text2[64] = "7654321 Now is the time for ";
+unsigned char clear_text3[64] = {2,0,0,0, 1,0,0,0};
+unsigned char output[64];
+unsigned char zero_text[8] = {0x0,0,0,0,0,0,0,0};
+unsigned char msb_text[8] = {0x0,0,0,0, 0,0,0,0x40}; /* to ANSI MSB */
+unsigned char *input;
+
+/* 0x0123456789abcdef */
+unsigned char default_key[8] = {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
+};
+unsigned char key2[8] = { 0x08,0x19,0x2a,0x3b,0x4c,0x5d,0x6e,0x7f };
+unsigned char key3[8] = { 0x80,1,1,1,1,1,1,1 };
+mit_des_cblock s_key;
+unsigned char default_ivec[8] = {
+ 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef
+};
+unsigned char *ivec;
+unsigned char zero_key[8] = {1,1,1,1,1,1,1,1}; /* just parity bits */
+
+unsigned char cipher1[8] = {
+ 0x25,0xdd,0xac,0x3e,0x96,0x17,0x64,0x67
+};
+unsigned char cipher2[8] = {
+ 0x3f,0xa4,0x0e,0x8a,0x98,0x4d,0x48,0x15
+};
+unsigned char cipher3[64] = {
+ 0xe5,0xc7,0xcd,0xde,0x87,0x2b,0xf2,0x7c,
+ 0x43,0xe9,0x34,0x00,0x8c,0x38,0x9c,0x0f,
+ 0x68,0x37,0x88,0x49,0x9a,0x7c,0x05,0xf6
+};
+unsigned char checksum[8] = {
+ 0x58,0xd2,0xe7,0x7e,0x86,0x06,0x27,0x33
+};
+
+unsigned char zresult[8] = {
+ 0x8c, 0xa6, 0x4d, 0xe9, 0xc1, 0xb1, 0x23, 0xa7
+};
+
+unsigned char mresult[8] = {
+ 0xa3, 0x80, 0xe0, 0x2a, 0x6b, 0xe5, 0x46, 0x96
+};
+
+
+/*
+ * Can also add :
+ * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?)
+ */
+
+mit_des_key_schedule sched;
+
+int
+main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ /* Local Declarations */
+ size_t in_length;
+ int retval;
+ int i, j;
+
+#ifdef WINDOWS
+ /* Set screen window buffer to infinite size -- MS default is tiny. */
+ _wsetscreenbuf (fileno (stdout), _WINBUFINF);
+#endif
+ progname=argv[0]; /* salt away invoking program */
+
+ while (--argc > 0 && (*++argv)[0] == '-')
+ for (i=1; argv[0][i] != '\0'; i++) {
+ switch (argv[0][i]) {
+
+ /* debug flag */
+ case 'd':
+ mit_des_debug=3;
+ continue;
+
+ case 'z':
+ zflag = 1;
+ continue;
+
+ case 'm':
+ mflag = 1;
+ continue;
+
+ default:
+ printf("%s: illegal flag \"%c\" ",
+ progname,argv[0][i]);
+ exit(1);
+ }
+ };
+
+ if (argc) {
+ fprintf(stderr, "Usage: %s [-dmz]\n", progname);
+ exit(1);
+ }
+
+ /* do some initialisation */
+
+ /* use known input and key */
+
+ /* ECB zero text zero key */
+ if (zflag) {
+ input = zero_text;
+ mit_des_key_sched(zero_key, sched);
+ printf("plaintext = key = 0, cipher = 0x8ca64de9c1b123a7\n");
+ do_encrypt(input,cipher_text);
+ printf("\tcipher = (low to high bytes)\n\t\t");
+ for (j = 0; j<=7; j++)
+ printf("%02x ",cipher_text[j]);
+ printf("\n");
+ do_decrypt(output,cipher_text);
+ if ( memcmp((char *)cipher_text, (char *)zresult, 8) ) {
+ printf("verify: error in zero key test\n");
+ exit(-1);
+ }
+
+ exit(0);
+ }
+
+ if (mflag) {
+ input = msb_text;
+ mit_des_key_sched(key3, sched);
+ printf("plaintext = 0x00 00 00 00 00 00 00 40, ");
+ printf("key = 0x80 01 01 01 01 01 01 01\n");
+ printf(" cipher = 0xa380e02a6be54696\n");
+ do_encrypt(input,cipher_text);
+ printf("\tcipher = (low to high bytes)\n\t\t");
+ for (j = 0; j<=7; j++) {
+ printf("%02x ",cipher_text[j]);
+ }
+ printf("\n");
+ do_decrypt(output,cipher_text);
+ if ( memcmp((char *)cipher_text, (char *)mresult, 8) ) {
+ printf("verify: error in msb test\n");
+ exit(-1);
+ }
+ exit(0);
+ }
+
+ /* ECB mode Davies and Price */
+ {
+ input = zero_text;
+ mit_des_key_sched(key2, sched);
+ printf("Examples per FIPS publication 81, keys ivs and cipher\n");
+ printf("in hex. These are the correct answers, see below for\n");
+ printf("the actual answers.\n\n");
+ printf("Examples per Davies and Price.\n\n");
+ printf("EXAMPLE ECB\tkey = 08192a3b4c5d6e7f\n");
+ printf("\tclear = 0\n");
+ printf("\tcipher = 25 dd ac 3e 96 17 64 67\n");
+ printf("ACTUAL ECB\n");
+ printf("\tclear \"%s\"\n", input);
+ do_encrypt(input,cipher_text);
+ printf("\tcipher = (low to high bytes)\n\t\t");
+ for (j = 0; j<=7; j++)
+ printf("%02x ",cipher_text[j]);
+ printf("\n\n");
+ do_decrypt(output,cipher_text);
+ if ( memcmp((char *)cipher_text, (char *)cipher1, 8) ) {
+ printf("verify: error in ECB encryption\n");
+ exit(-1);
+ }
+ else
+ printf("verify: ECB encryption is correct\n\n");
+ }
+
+ /* ECB mode */
+ {
+ mit_des_key_sched(default_key, sched);
+ input = clear_text;
+ ivec = default_ivec;
+ printf("EXAMPLE ECB\tkey = 0123456789abcdef\n");
+ printf("\tclear = \"Now is the time for all \"\n");
+ printf("\tcipher = 3f a4 0e 8a 98 4d 48 15 ...\n");
+ printf("ACTUAL ECB\n\tclear \"%s\"",input);
+ do_encrypt(input,cipher_text);
+ printf("\n\tcipher = (low to high bytes)\n\t\t");
+ for (j = 0; j<=7; j++) {
+ printf("%02x ",cipher_text[j]);
+ }
+ printf("\n\n");
+ do_decrypt(output,cipher_text);
+ if ( memcmp((char *)cipher_text, (char *)cipher2, 8) ) {
+ printf("verify: error in ECB encryption\n");
+ exit(-1);
+ }
+ else
+ printf("verify: ECB encryption is correct\n\n");
+ }
+
+ /* CBC mode */
+ printf("EXAMPLE CBC\tkey = 0123456789abcdef");
+ printf("\tiv = 1234567890abcdef\n");
+ printf("\tclear = \"Now is the time for all \"\n");
+ printf("\tcipher =\te5 c7 cd de 87 2b f2 7c\n");
+ printf("\t\t\t43 e9 34 00 8c 38 9c 0f\n");
+ printf("\t\t\t68 37 88 49 9a 7c 05 f6\n");
+
+ printf("ACTUAL CBC\n\tclear \"%s\"\n",input);
+ in_length = strlen((char *)input);
+ if ((retval = mit_des_cbc_encrypt((const mit_des_cblock *) input,
+ (mit_des_cblock *) cipher_text,
+ (size_t) in_length,
+ sched,
+ ivec,
+ MIT_DES_ENCRYPT))) {
+ com_err("des verify", retval, "can't encrypt");
+ exit(-1);
+ }
+ printf("\tciphertext = (low to high bytes)\n");
+ for (i = 0; i <= 2; i++) {
+ printf("\t\t");
+ for (j = 0; j <= 7; j++) {
+ printf("%02x ",cipher_text[i*8+j]);
+ }
+ printf("\n");
+ }
+ if ((retval = mit_des_cbc_encrypt((const mit_des_cblock *) cipher_text,
+ (mit_des_cblock *) clear_text,
+ (size_t) in_length,
+ sched,
+ ivec,
+ MIT_DES_DECRYPT))) {
+ com_err("des verify", retval, "can't decrypt");
+ exit(-1);
+ }
+ printf("\tdecrypted clear_text = \"%s\"\n",clear_text);
+
+ if ( memcmp((char *)cipher_text, (char *)cipher3, in_length) ) {
+ printf("verify: error in CBC encryption\n");
+ exit(-1);
+ }
+ else
+ printf("verify: CBC encryption is correct\n\n");
+
+ printf("EXAMPLE CBC checksum");
+ printf("\tkey = 0123456789abcdef\tiv = 1234567890abcdef\n");
+ printf("\tclear =\t\t\"7654321 Now is the time for \"\n");
+ printf("\tchecksum\t58 d2 e7 7e 86 06 27 33, ");
+ printf("or some part thereof\n");
+ input = clear_text2;
+ mit_des_cbc_cksum(input,cipher_text, strlen((char *)input),
+ sched,ivec);
+ printf("ACTUAL CBC checksum\n");
+ printf("\t\tencrypted cksum = (low to high bytes)\n\t\t");
+ for (j = 0; j<=7; j++)
+ printf("%02x ",cipher_text[j]);
+ printf("\n\n");
+ if ( memcmp((char *)cipher_text, (char *)checksum, 8) ) {
+ printf("verify: error in CBC cheksum\n");
+ exit(-1);
+ }
+ else
+ printf("verify: CBC checksum is correct\n\n");
+
+ exit(0);
+}
+
+#if 0
+void
+flip(array)
+ char *array;
+{
+ register int old,new,i,j;
+ /* flips the bit order within each byte from 0 lsb to 0 msb */
+ for (i = 0; i<=7; i++) {
+ old = *array;
+ new = 0;
+ for (j = 0; j<=7; j++) {
+ if (old & 01)
+ new = new | 01;
+ if (j < 7) {
+ old = old >> 1;
+ new = new << 1;
+ }
+ }
+ *array = new;
+ array++;
+ }
+}
+#endif
+
+static void
+do_encrypt(in,out)
+ unsigned char *in;
+ unsigned char *out;
+{
+ int i, j;
+ for (i =1; i<=nflag; i++) {
+ mit_des_cbc_encrypt((const mit_des_cblock *)in,
+ (mit_des_cblock *)out,
+ 8,
+ sched,
+ zero_text,
+ MIT_DES_ENCRYPT);
+ if (mit_des_debug) {
+ printf("\nclear %s\n",in);
+ for (j = 0; j<=7; j++)
+ printf("%02X ",in[j] & 0xff);
+ printf("\tcipher ");
+ for (j = 0; j<=7; j++)
+ printf("%02X ",out[j] & 0xff);
+ }
+ }
+}
+
+static void
+do_decrypt(in,out)
+ unsigned char *out;
+ unsigned char *in;
+ /* try to invert it */
+{
+ int i, j;
+ for (i =1; i<=nflag; i++) {
+ mit_des_cbc_encrypt((const mit_des_cblock *)out,
+ (mit_des_cblock *)in,
+ 8,
+ sched,
+ zero_text,
+ MIT_DES_DECRYPT);
+ if (mit_des_debug) {
+ printf("clear %s\n",in);
+ for (j = 0; j<=7; j++)
+ printf("%02X ",in[j] & 0xff);
+ printf("\tcipher ");
+ for (j = 0; j<=7; j++)
+ printf("%02X ",out[j] & 0xff);
+ }
+ }
+}
+
+/*
+ * Fake out the DES library, for the purposes of testing.
+ */
+
+int
+mit_des_is_weak_key(key)
+ mit_des_cblock key;
+{
+ return 0; /* fake it out for testing */
+}
diff --git a/src/lib/crypto/builtin/des/weak_key.c b/src/lib/crypto/builtin/des/weak_key.c
new file mode 100644
index 000000000000..eb41b267dfd5
--- /dev/null
+++ b/src/lib/crypto/builtin/des/weak_key.c
@@ -0,0 +1,86 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/des/weak_key.c */
+/*
+ * Copyright 1989,1990 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+/*
+ * Under U.S. law, this software may not be exported outside the US
+ * without license from the U.S. Commerce department.
+ *
+ * These routines form the library interface to the DES facilities.
+ *
+ * Originally written 8/85 by Steve Miller, MIT Project Athena.
+ */
+
+#include "k5-int.h"
+#include "des_int.h"
+
+/*
+ * The following are the weak DES keys:
+ */
+static const mit_des_cblock weak[16] = {
+ /* weak keys */
+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+ {0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe},
+ {0x1f,0x1f,0x1f,0x1f,0x0e,0x0e,0x0e,0x0e},
+ {0xe0,0xe0,0xe0,0xe0,0xf1,0xf1,0xf1,0xf1},
+
+ /* semi-weak */
+ {0x01,0xfe,0x01,0xfe,0x01,0xfe,0x01,0xfe},
+ {0xfe,0x01,0xfe,0x01,0xfe,0x01,0xfe,0x01},
+
+ {0x1f,0xe0,0x1f,0xe0,0x0e,0xf1,0x0e,0xf1},
+ {0xe0,0x1f,0xe0,0x1f,0xf1,0x0e,0xf1,0x0e},
+
+ {0x01,0xe0,0x01,0xe0,0x01,0xf1,0x01,0xf1},
+ {0xe0,0x01,0xe0,0x01,0xf1,0x01,0xf1,0x01},
+
+ {0x1f,0xfe,0x1f,0xfe,0x0e,0xfe,0x0e,0xfe},
+ {0xfe,0x1f,0xfe,0x1f,0xfe,0x0e,0xfe,0x0e},
+
+ {0x01,0x1f,0x01,0x1f,0x01,0x0e,0x01,0x0e},
+ {0x1f,0x01,0x1f,0x01,0x0e,0x01,0x0e,0x01},
+
+ {0xe0,0xfe,0xe0,0xfe,0xf1,0xfe,0xf1,0xfe},
+ {0xfe,0xe0,0xfe,0xe0,0xfe,0xf1,0xfe,0xf1}
+};
+
+/*
+ * mit_des_is_weak_key: returns true iff key is a [semi-]weak des key.
+ *
+ * Requires: key has correct odd parity.
+ */
+int
+mit_des_is_weak_key(mit_des_cblock key)
+{
+ unsigned int i;
+ const mit_des_cblock *weak_p = weak;
+
+ for (i = 0; i < (sizeof(weak)/sizeof(mit_des_cblock)); i++) {
+ if (!memcmp(weak_p++,key,sizeof(mit_des_cblock)))
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/lib/crypto/builtin/enc_provider/Makefile.in b/src/lib/crypto/builtin/enc_provider/Makefile.in
new file mode 100644
index 000000000000..4fd3311b4fb1
--- /dev/null
+++ b/src/lib/crypto/builtin/enc_provider/Makefile.in
@@ -0,0 +1,45 @@
+mydir=lib$(S)crypto$(S)builtin$(S)enc_provider
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+LOCALINCLUDES = -I$(srcdir)/../des \
+ -I$(srcdir)/../aes \
+ -I$(srcdir)/../camellia \
+ -I$(srcdir)/../../krb \
+ -I$(srcdir)/..
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR = builtin\enc_provider
+##DOS##OBJFILE = ..\..\$(OUTPRE)enc_provider.lst
+
+STLIBOBJS= \
+ des.o \
+ des3.o \
+ rc4.o \
+ aes.o \
+ camellia.o
+
+OBJS= \
+ $(OUTPRE)des.$(OBJEXT) \
+ $(OUTPRE)des3.$(OBJEXT) \
+ $(OUTPRE)aes.$(OBJEXT) \
+ $(OUTPRE)camellia.$(OBJEXT) \
+ $(OUTPRE)rc4.$(OBJEXT)
+
+SRCS= \
+ $(srcdir)/des.c \
+ $(srcdir)/des3.c \
+ $(srcdir)/aes.c \
+ $(srcdir)/camellia.c \
+ $(srcdir)/rc4.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix: all-libobjs
+
+includes: depend
+
+depend: $(SRCS)
+
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/enc_provider/aes.c b/src/lib/crypto/builtin/enc_provider/aes.c
new file mode 100644
index 000000000000..2a5d8e39775d
--- /dev/null
+++ b/src/lib/crypto/builtin/enc_provider/aes.c
@@ -0,0 +1,406 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/enc_provider/aes.c */
+/*
+ * Copyright (C) 2003, 2007, 2008 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "crypto_int.h"
+#include "aes.h"
+
+/*
+ * Private per-key data to cache after first generation. We don't
+ * want to mess with the imported AES implementation too much, so
+ * we'll just use two copies of its context, one for encryption and
+ * one for decryption, and use the #rounds field as a flag for whether
+ * we've initialized each half.
+ */
+struct aes_key_info_cache {
+ aes_ctx enc_ctx, dec_ctx;
+ krb5_boolean aesni;
+};
+#define CACHE(X) ((struct aes_key_info_cache *)((X)->cache))
+
+#ifdef AESNI
+
+/* Use AES-NI instructions (via assembly functions) when possible. */
+
+#include <cpuid.h>
+
+struct aes_data
+{
+ unsigned char *in_block;
+ unsigned char *out_block;
+ uint32_t *expanded_key;
+ unsigned char *iv;
+ size_t num_blocks;
+};
+
+void k5_iEncExpandKey128(unsigned char *key, uint32_t *expanded_key);
+void k5_iEncExpandKey256(unsigned char *key, uint32_t *expanded_key);
+void k5_iDecExpandKey256(unsigned char *key, uint32_t *expanded_key);
+void k5_iDecExpandKey128(unsigned char *key, uint32_t *expanded_key);
+
+void k5_iEnc128_CBC(struct aes_data *data);
+void k5_iDec128_CBC(struct aes_data *data);
+void k5_iEnc256_CBC(struct aes_data *data);
+void k5_iDec256_CBC(struct aes_data *data);
+
+static krb5_boolean
+aesni_supported_by_cpu()
+{
+ unsigned int a, b, c, d;
+
+ return __get_cpuid(1, &a, &b, &c, &d) && (c & (1 << 25));
+}
+
+static inline krb5_boolean
+aesni_supported(krb5_key key)
+{
+ return CACHE(key)->aesni;
+}
+
+static void
+aesni_expand_enc_key(krb5_key key)
+{
+ struct aes_key_info_cache *cache = CACHE(key);
+
+ if (key->keyblock.length == 16)
+ k5_iEncExpandKey128(key->keyblock.contents, cache->enc_ctx.k_sch);
+ else
+ k5_iEncExpandKey256(key->keyblock.contents, cache->enc_ctx.k_sch);
+ cache->enc_ctx.n_rnd = 1;
+}
+
+static void
+aesni_expand_dec_key(krb5_key key)
+{
+ struct aes_key_info_cache *cache = CACHE(key);
+
+ if (key->keyblock.length == 16)
+ k5_iDecExpandKey128(key->keyblock.contents, cache->dec_ctx.k_sch);
+ else
+ k5_iDecExpandKey256(key->keyblock.contents, cache->dec_ctx.k_sch);
+ cache->dec_ctx.n_rnd = 1;
+}
+
+static inline void
+aesni_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
+{
+ struct aes_key_info_cache *cache = CACHE(key);
+ struct aes_data d;
+
+ d.in_block = data;
+ d.out_block = data;
+ d.expanded_key = cache->enc_ctx.k_sch;
+ d.iv = iv;
+ d.num_blocks = nblocks;
+ if (key->keyblock.length == 16)
+ k5_iEnc128_CBC(&d);
+ else
+ k5_iEnc256_CBC(&d);
+}
+
+static inline void
+aesni_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
+{
+ struct aes_key_info_cache *cache = CACHE(key);
+ struct aes_data d;
+
+ d.in_block = data;
+ d.out_block = data;
+ d.expanded_key = cache->dec_ctx.k_sch;
+ d.iv = iv;
+ d.num_blocks = nblocks;
+ if (key->keyblock.length == 16)
+ k5_iDec128_CBC(&d);
+ else
+ k5_iDec256_CBC(&d);
+}
+
+#else /* not AESNI */
+
+#define aesni_supported_by_cpu() FALSE
+#define aesni_supported(key) FALSE
+#define aesni_expand_enc_key(key)
+#define aesni_expand_dec_key(key)
+#define aesni_enc(key, data, nblocks, iv)
+#define aesni_dec(key, data, nblocks, iv)
+
+#endif
+
+/* out = out ^ in */
+static inline void
+xorblock(const unsigned char *in, unsigned char *out)
+{
+ size_t q;
+
+ for (q = 0; q < BLOCK_SIZE; q += 4)
+ store_32_n(load_32_n(out + q) ^ load_32_n(in + q), out + q);
+}
+
+static inline krb5_error_code
+init_key_cache(krb5_key key)
+{
+ if (key->cache != NULL)
+ return 0;
+ key->cache = malloc(sizeof(struct aes_key_info_cache));
+ if (key->cache == NULL)
+ return ENOMEM;
+ CACHE(key)->enc_ctx.n_rnd = CACHE(key)->dec_ctx.n_rnd = 0;
+ CACHE(key)->aesni = aesni_supported_by_cpu();
+ return 0;
+}
+
+static inline void
+expand_enc_key(krb5_key key)
+{
+ if (CACHE(key)->enc_ctx.n_rnd)
+ return;
+ if (aesni_supported(key))
+ aesni_expand_enc_key(key);
+ else if (aes_enc_key(key->keyblock.contents, key->keyblock.length,
+ &CACHE(key)->enc_ctx) != aes_good)
+ abort();
+}
+
+static inline void
+expand_dec_key(krb5_key key)
+{
+ if (CACHE(key)->dec_ctx.n_rnd)
+ return;
+ if (aesni_supported(key))
+ aesni_expand_dec_key(key);
+ else if (aes_dec_key(key->keyblock.contents, key->keyblock.length,
+ &CACHE(key)->dec_ctx) != aes_good)
+ abort();
+}
+
+/* CBC encrypt nblocks blocks of data in place, using and updating iv. */
+static inline void
+cbc_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
+{
+ if (aesni_supported(key)) {
+ aesni_enc(key, data, nblocks, iv);
+ return;
+ }
+ for (; nblocks > 0; nblocks--, data += BLOCK_SIZE) {
+ xorblock(iv, data);
+ if (aes_enc_blk(data, data, &CACHE(key)->enc_ctx) != aes_good)
+ abort();
+ memcpy(iv, data, BLOCK_SIZE);
+ }
+}
+
+/* CBC decrypt nblocks blocks of data in place, using and updating iv. */
+static inline void
+cbc_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
+{
+ unsigned char last_cipherblock[BLOCK_SIZE];
+
+ if (aesni_supported(key)) {
+ aesni_dec(key, data, nblocks, iv);
+ return;
+ }
+ assert(nblocks > 0);
+ data += (nblocks - 1) * BLOCK_SIZE;
+ memcpy(last_cipherblock, data, BLOCK_SIZE);
+ for (; nblocks > 0; nblocks--, data -= BLOCK_SIZE) {
+ if (aes_dec_blk(data, data, &CACHE(key)->dec_ctx) != aes_good)
+ abort();
+ xorblock(nblocks == 1 ? iv : data - BLOCK_SIZE, data);
+ }
+ memcpy(iv, last_cipherblock, BLOCK_SIZE);
+}
+
+krb5_error_code
+krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+ size_t num_data)
+{
+ unsigned char iv[BLOCK_SIZE], block[BLOCK_SIZE];
+ unsigned char blockN2[BLOCK_SIZE], blockN1[BLOCK_SIZE];
+ size_t input_length, nblocks, ncontig;
+ struct iov_cursor cursor;
+
+ if (init_key_cache(key))
+ return ENOMEM;
+ expand_enc_key(key);
+
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+
+ input_length = iov_total_length(data, num_data, FALSE);
+ nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ if (nblocks == 1) {
+ k5_iov_cursor_get(&cursor, block);
+ memset(iv, 0, BLOCK_SIZE);
+ cbc_enc(key, block, 1, iv);
+ k5_iov_cursor_put(&cursor, block);
+ return 0;
+ }
+
+ if (ivec != NULL)
+ memcpy(iv, ivec->data, BLOCK_SIZE);
+ else
+ memset(iv, 0, BLOCK_SIZE);
+
+ while (nblocks > 2) {
+ ncontig = iov_cursor_contig_blocks(&cursor);
+ if (ncontig > 0) {
+ /* Encrypt a series of contiguous blocks in place if we can, but
+ * don't touch the last two blocks. */
+ ncontig = (ncontig > nblocks - 2) ? nblocks - 2 : ncontig;
+ cbc_enc(key, iov_cursor_ptr(&cursor), ncontig, iv);
+ iov_cursor_advance(&cursor, ncontig);
+ nblocks -= ncontig;
+ } else {
+ k5_iov_cursor_get(&cursor, block);
+ cbc_enc(key, block, 1, iv);
+ k5_iov_cursor_put(&cursor, block);
+ nblocks--;
+ }
+ }
+
+ /* Encrypt the last two blocks and put them back in reverse order, possibly
+ * truncating the encrypted second-to-last block. */
+ k5_iov_cursor_get(&cursor, blockN2);
+ k5_iov_cursor_get(&cursor, blockN1);
+ cbc_enc(key, blockN2, 1, iv);
+ cbc_enc(key, blockN1, 1, iv);
+ k5_iov_cursor_put(&cursor, blockN1);
+ k5_iov_cursor_put(&cursor, blockN2);
+
+ if (ivec != NULL)
+ memcpy(ivec->data, iv, BLOCK_SIZE);
+
+ return 0;
+}
+
+krb5_error_code
+krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+ size_t num_data)
+{
+ unsigned char iv[BLOCK_SIZE], dummy_iv[BLOCK_SIZE], block[BLOCK_SIZE];
+ unsigned char blockN2[BLOCK_SIZE], blockN1[BLOCK_SIZE];
+ size_t input_length, last_len, nblocks, ncontig;
+ struct iov_cursor cursor;
+
+ if (init_key_cache(key))
+ return ENOMEM;
+ expand_dec_key(key);
+
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+
+ input_length = iov_total_length(data, num_data, FALSE);
+ nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ last_len = input_length - (nblocks - 1) * BLOCK_SIZE;
+ if (nblocks == 1) {
+ k5_iov_cursor_get(&cursor, block);
+ memset(iv, 0, BLOCK_SIZE);
+ cbc_dec(key, block, 1, iv);
+ k5_iov_cursor_put(&cursor, block);
+ return 0;
+ }
+
+ if (ivec != NULL)
+ memcpy(iv, ivec->data, BLOCK_SIZE);
+ else
+ memset(iv, 0, BLOCK_SIZE);
+
+ while (nblocks > 2) {
+ ncontig = iov_cursor_contig_blocks(&cursor);
+ if (ncontig > 0) {
+ /* Decrypt a series of contiguous blocks in place if we can, but
+ * don't touch the last two blocks. */
+ ncontig = (ncontig > nblocks - 2) ? nblocks - 2 : ncontig;
+ cbc_dec(key, iov_cursor_ptr(&cursor), ncontig, iv);
+ iov_cursor_advance(&cursor, ncontig);
+ nblocks -= ncontig;
+ } else {
+ k5_iov_cursor_get(&cursor, block);
+ cbc_dec(key, block, 1, iv);
+ k5_iov_cursor_put(&cursor, block);
+ nblocks--;
+ }
+ }
+
+ /* Get the last two ciphertext blocks. Save the first as the new iv. */
+ k5_iov_cursor_get(&cursor, blockN2);
+ k5_iov_cursor_get(&cursor, blockN1);
+ if (ivec != NULL)
+ memcpy(ivec->data, blockN2, BLOCK_SIZE);
+
+ /* Decrypt the second-to-last ciphertext block, using the final ciphertext
+ * block as the CBC IV. This produces the final plaintext block. */
+ memcpy(dummy_iv, blockN1, sizeof(dummy_iv));
+ cbc_dec(key, blockN2, 1, dummy_iv);
+
+ /* Use the final bits of the decrypted plaintext to pad the last ciphertext
+ * block, and decrypt it to produce the second-to-last plaintext block. */
+ memcpy(blockN1 + last_len, blockN2 + last_len, BLOCK_SIZE - last_len);
+ cbc_dec(key, blockN1, 1, iv);
+
+ /* Put the last two plaintext blocks back into the iovec. */
+ k5_iov_cursor_put(&cursor, blockN1);
+ k5_iov_cursor_put(&cursor, blockN2);
+
+ return 0;
+}
+
+static krb5_error_code
+aes_init_state(const krb5_keyblock *key, krb5_keyusage usage,
+ krb5_data *state)
+{
+ state->length = 16;
+ state->data = malloc(16);
+ if (state->data == NULL)
+ return ENOMEM;
+ memset(state->data, 0, state->length);
+ return 0;
+}
+
+static void
+aes_key_cleanup(krb5_key key)
+{
+ zapfree(key->cache, sizeof(struct aes_key_info_cache));
+}
+
+const struct krb5_enc_provider krb5int_enc_aes128 = {
+ 16,
+ 16, 16,
+ krb5int_aes_encrypt,
+ krb5int_aes_decrypt,
+ NULL,
+ aes_init_state,
+ krb5int_default_free_state,
+ aes_key_cleanup
+};
+
+const struct krb5_enc_provider krb5int_enc_aes256 = {
+ 16,
+ 32, 32,
+ krb5int_aes_encrypt,
+ krb5int_aes_decrypt,
+ NULL,
+ aes_init_state,
+ krb5int_default_free_state,
+ aes_key_cleanup
+};
diff --git a/src/lib/crypto/builtin/enc_provider/camellia.c b/src/lib/crypto/builtin/enc_provider/camellia.c
new file mode 100644
index 000000000000..db1258086798
--- /dev/null
+++ b/src/lib/crypto/builtin/enc_provider/camellia.c
@@ -0,0 +1,315 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/enc_provider/camellia.c - Camellia enc provider */
+/*
+ * Copyright (C) 2009, 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "crypto_int.h"
+#include "camellia.h"
+
+/*
+ * Private per-key data to cache after first generation. We don't want to mess
+ * with the imported Camellia implementation too much, so we'll just use two
+ * copies of its context, one for encryption and one for decryption, and use
+ * the keybitlen field as a flag for whether we've initialized each half.
+ */
+struct camellia_key_info_cache {
+ camellia_ctx enc_ctx, dec_ctx;
+};
+#define CACHE(X) ((struct camellia_key_info_cache *)((X)->cache))
+
+/* out = out ^ in */
+static inline void
+xorblock(const unsigned char *in, unsigned char *out)
+{
+ size_t q;
+
+ for (q = 0; q < BLOCK_SIZE; q += 4)
+ store_32_n(load_32_n(out + q) ^ load_32_n(in + q), out + q);
+}
+
+static inline krb5_error_code
+init_key_cache(krb5_key key)
+{
+ if (key->cache != NULL)
+ return 0;
+ key->cache = malloc(sizeof(struct camellia_key_info_cache));
+ if (key->cache == NULL)
+ return ENOMEM;
+ CACHE(key)->enc_ctx.keybitlen = CACHE(key)->dec_ctx.keybitlen = 0;
+ return 0;
+}
+
+static inline void
+expand_enc_key(krb5_key key)
+{
+ if (CACHE(key)->enc_ctx.keybitlen)
+ return;
+ if (camellia_enc_key(key->keyblock.contents, key->keyblock.length,
+ &CACHE(key)->enc_ctx) != camellia_good)
+ abort();
+}
+
+static inline void
+expand_dec_key(krb5_key key)
+{
+ if (CACHE(key)->dec_ctx.keybitlen)
+ return;
+ if (camellia_dec_key(key->keyblock.contents, key->keyblock.length,
+ &CACHE(key)->dec_ctx) != camellia_good)
+ abort();
+}
+
+/* CBC encrypt nblocks blocks of data in place, using and updating iv. */
+static inline void
+cbc_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
+{
+ for (; nblocks > 0; nblocks--, data += BLOCK_SIZE) {
+ xorblock(iv, data);
+ if (camellia_enc_blk(data, data, &CACHE(key)->enc_ctx) !=
+ camellia_good)
+ abort();
+ memcpy(iv, data, BLOCK_SIZE);
+ }
+}
+
+/* CBC decrypt nblocks blocks of data in place, using and updating iv. */
+static inline void
+cbc_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
+{
+ unsigned char last_cipherblock[BLOCK_SIZE];
+
+ assert(nblocks > 0);
+ data += (nblocks - 1) * BLOCK_SIZE;
+ memcpy(last_cipherblock, data, BLOCK_SIZE);
+ for (; nblocks > 0; nblocks--, data -= BLOCK_SIZE) {
+ if (camellia_dec_blk(data, data, &CACHE(key)->dec_ctx) !=
+ camellia_good)
+ abort();
+ xorblock(nblocks == 1 ? iv : data - BLOCK_SIZE, data);
+ }
+ memcpy(iv, last_cipherblock, BLOCK_SIZE);
+}
+
+static krb5_error_code
+krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ unsigned char iv[BLOCK_SIZE], block[BLOCK_SIZE];
+ unsigned char blockN2[BLOCK_SIZE], blockN1[BLOCK_SIZE];
+ size_t input_length, nblocks, ncontig;
+ struct iov_cursor cursor;
+
+ if (init_key_cache(key))
+ return ENOMEM;
+ expand_enc_key(key);
+
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+
+ input_length = iov_total_length(data, num_data, FALSE);
+ nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ if (nblocks == 1) {
+ k5_iov_cursor_get(&cursor, block);
+ memset(iv, 0, BLOCK_SIZE);
+ cbc_enc(key, block, 1, iv);
+ k5_iov_cursor_put(&cursor, block);
+ return 0;
+ }
+
+ if (ivec != NULL)
+ memcpy(iv, ivec->data, BLOCK_SIZE);
+ else
+ memset(iv, 0, BLOCK_SIZE);
+
+ while (nblocks > 2) {
+ ncontig = iov_cursor_contig_blocks(&cursor);
+ if (ncontig > 0) {
+ /* Encrypt a series of contiguous blocks in place if we can, but
+ * don't touch the last two blocks. */
+ ncontig = (ncontig > nblocks - 2) ? nblocks - 2 : ncontig;
+ cbc_enc(key, iov_cursor_ptr(&cursor), ncontig, iv);
+ iov_cursor_advance(&cursor, ncontig);
+ nblocks -= ncontig;
+ } else {
+ k5_iov_cursor_get(&cursor, block);
+ cbc_enc(key, block, 1, iv);
+ k5_iov_cursor_put(&cursor, block);
+ nblocks--;
+ }
+ }
+
+ /* Encrypt the last two blocks and put them back in reverse order, possibly
+ * truncating the encrypted second-to-last block. */
+ k5_iov_cursor_get(&cursor, blockN2);
+ k5_iov_cursor_get(&cursor, blockN1);
+ cbc_enc(key, blockN2, 1, iv);
+ cbc_enc(key, blockN1, 1, iv);
+ k5_iov_cursor_put(&cursor, blockN1);
+ k5_iov_cursor_put(&cursor, blockN2);
+
+ if (ivec != NULL)
+ memcpy(ivec->data, iv, BLOCK_SIZE);
+
+ return 0;
+}
+
+static krb5_error_code
+krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ unsigned char iv[BLOCK_SIZE], dummy_iv[BLOCK_SIZE], block[BLOCK_SIZE];
+ unsigned char blockN2[BLOCK_SIZE], blockN1[BLOCK_SIZE];
+ size_t input_length, last_len, nblocks, ncontig;
+ struct iov_cursor cursor;
+
+ if (init_key_cache(key))
+ return ENOMEM;
+ expand_dec_key(key);
+
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+
+ input_length = iov_total_length(data, num_data, FALSE);
+ nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ last_len = input_length - (nblocks - 1) * BLOCK_SIZE;
+ if (nblocks == 1) {
+ k5_iov_cursor_get(&cursor, block);
+ memset(iv, 0, BLOCK_SIZE);
+ cbc_dec(key, block, 1, iv);
+ k5_iov_cursor_put(&cursor, block);
+ return 0;
+ }
+
+ if (ivec != NULL)
+ memcpy(iv, ivec->data, BLOCK_SIZE);
+ else
+ memset(iv, 0, BLOCK_SIZE);
+
+ while (nblocks > 2) {
+ ncontig = iov_cursor_contig_blocks(&cursor);
+ if (ncontig > 0) {
+ /* Encrypt a series of contiguous blocks in place if we can, but
+ * don't touch the last two blocks. */
+ ncontig = (ncontig > nblocks - 2) ? nblocks - 2 : ncontig;
+ cbc_dec(key, iov_cursor_ptr(&cursor), ncontig, iv);
+ iov_cursor_advance(&cursor, ncontig);
+ nblocks -= ncontig;
+ } else {
+ k5_iov_cursor_get(&cursor, block);
+ cbc_dec(key, block, 1, iv);
+ k5_iov_cursor_put(&cursor, block);
+ nblocks--;
+ }
+ }
+
+ /* Get the last two ciphertext blocks. Save the first as the new iv. */
+ k5_iov_cursor_get(&cursor, blockN2);
+ k5_iov_cursor_get(&cursor, blockN1);
+ if (ivec != NULL)
+ memcpy(ivec->data, blockN2, BLOCK_SIZE);
+
+ /* Decrypt the second-to-last ciphertext block, using the final ciphertext
+ * block as the CBC IV. This produces the final plaintext block. */
+ memcpy(dummy_iv, blockN1, sizeof(dummy_iv));
+ cbc_dec(key, blockN2, 1, dummy_iv);
+
+ /* Use the final bits of the decrypted plaintext to pad the last ciphertext
+ * block, and decrypt it to produce the second-to-last plaintext block. */
+ memcpy(blockN1 + last_len, blockN2 + last_len, BLOCK_SIZE - last_len);
+ cbc_dec(key, blockN1, 1, iv);
+
+ /* Put the last two plaintext blocks back into the iovec. */
+ k5_iov_cursor_put(&cursor, blockN1);
+ k5_iov_cursor_put(&cursor, blockN2);
+
+ return 0;
+}
+
+krb5_error_code
+krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
+ size_t num_data, const krb5_data *ivec,
+ krb5_data *output)
+{
+ unsigned char iv[BLOCK_SIZE], block[BLOCK_SIZE];
+ struct iov_cursor cursor;
+
+ if (output->length < BLOCK_SIZE)
+ return KRB5_BAD_MSIZE;
+
+ if (init_key_cache(key))
+ return ENOMEM;
+ expand_enc_key(key);
+
+ if (ivec != NULL)
+ memcpy(iv, ivec->data, BLOCK_SIZE);
+ else
+ memset(iv, 0, BLOCK_SIZE);
+
+ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+ while (k5_iov_cursor_get(&cursor, block))
+ cbc_enc(key, block, 1, iv);
+
+ output->length = BLOCK_SIZE;
+ memcpy(output->data, iv, BLOCK_SIZE);
+
+ return 0;
+}
+
+static krb5_error_code
+camellia_init_state(const krb5_keyblock *key, krb5_keyusage usage,
+ krb5_data *state)
+{
+ state->length = 16;
+ state->data = malloc(16);
+ if (state->data == NULL)
+ return ENOMEM;
+ memset(state->data, 0, state->length);
+ return 0;
+}
+
+static void
+camellia_key_cleanup(krb5_key key)
+{
+ zapfree(key->cache, sizeof(struct camellia_key_info_cache));
+}
+
+const struct krb5_enc_provider krb5int_enc_camellia128 = {
+ 16,
+ 16, 16,
+ krb5int_camellia_encrypt,
+ krb5int_camellia_decrypt,
+ krb5int_camellia_cbc_mac,
+ camellia_init_state,
+ krb5int_default_free_state,
+ camellia_key_cleanup
+};
+
+const struct krb5_enc_provider krb5int_enc_camellia256 = {
+ 16,
+ 32, 32,
+ krb5int_camellia_encrypt,
+ krb5int_camellia_decrypt,
+ krb5int_camellia_cbc_mac,
+ camellia_init_state,
+ krb5int_default_free_state,
+ camellia_key_cleanup
+};
diff --git a/src/lib/crypto/builtin/enc_provider/deps b/src/lib/crypto/builtin/enc_provider/deps
new file mode 100644
index 000000000000..72e34076684c
--- /dev/null
+++ b/src/lib/crypto/builtin/enc_provider/deps
@@ -0,0 +1,64 @@
+#
+# Generated makefile dependencies follow.
+#
+des.so des.po $(OUTPRE)des.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
+ $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../des/des_int.h \
+ $(srcdir)/../sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h des.c
+des3.so des3.po $(OUTPRE)des3.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
+ $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../des/des_int.h \
+ $(srcdir)/../sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h des3.c
+aes.so aes.po $(OUTPRE)aes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
+ $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ aes.c
+camellia.so camellia.po $(OUTPRE)camellia.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../aes/aes.h \
+ $(srcdir)/../camellia/camellia.h $(srcdir)/../crypto_mod.h \
+ $(srcdir)/../sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h camellia.c
+rc4.so rc4.po $(OUTPRE)rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
+ $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ rc4.c
diff --git a/src/lib/crypto/builtin/enc_provider/des.c b/src/lib/crypto/builtin/enc_provider/des.c
new file mode 100644
index 000000000000..30b8229f8c6f
--- /dev/null
+++ b/src/lib/crypto/builtin/enc_provider/des.c
@@ -0,0 +1,120 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "crypto_int.h"
+#include "des_int.h"
+
+static krb5_error_code
+validate_and_schedule(krb5_key key, const krb5_data *ivec,
+ const krb5_crypto_iov *data, size_t num_data,
+ mit_des_key_schedule schedule)
+{
+ if (key->keyblock.length != 8)
+ return KRB5_BAD_KEYSIZE;
+ if (iov_total_length(data, num_data, FALSE) % 8 != 0)
+ return KRB5_BAD_MSIZE;
+ if (ivec != NULL && ivec->length != 8)
+ return KRB5_BAD_MSIZE;
+
+ switch (mit_des_key_sched(key->keyblock.contents, schedule)) {
+ case -1:
+ return(KRB5DES_BAD_KEYPAR);
+ case -2:
+ return(KRB5DES_WEAK_KEY);
+ }
+ return 0;
+}
+
+static krb5_error_code
+des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+ size_t num_data)
+{
+ mit_des_key_schedule schedule;
+ krb5_error_code err;
+
+ err = validate_and_schedule(key, ivec, data, num_data, schedule);
+ if (err)
+ return err;
+
+ krb5int_des_cbc_encrypt(data, num_data, schedule,
+ ivec != NULL ? (unsigned char *) ivec->data :
+ NULL);
+
+ zap(schedule, sizeof(schedule));
+ return 0;
+}
+
+static krb5_error_code
+des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+ size_t num_data)
+{
+ mit_des_key_schedule schedule;
+ krb5_error_code err;
+
+ err = validate_and_schedule(key, ivec, data, num_data, schedule);
+ if (err)
+ return err;
+
+ krb5int_des_cbc_decrypt(data, num_data, schedule,
+ ivec != NULL ? (unsigned char *) ivec->data :
+ NULL);
+
+ zap(schedule, sizeof(schedule));
+ return 0;
+}
+
+static krb5_error_code
+des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
+ const krb5_data *ivec, krb5_data *output)
+{
+ mit_des_key_schedule schedule;
+ krb5_error_code err;
+
+ err = validate_and_schedule(key, ivec, data, num_data, schedule);
+ if (err)
+ return err;
+
+ if (output->length != 8)
+ return KRB5_CRYPTO_INTERNAL;
+
+ krb5int_des_cbc_mac(data, num_data, schedule,
+ ivec != NULL ? (unsigned char *) ivec->data : NULL,
+ (unsigned char *) output->data);
+
+ zap(schedule, sizeof(schedule));
+ return 0;
+}
+
+const struct krb5_enc_provider krb5int_enc_des = {
+ 8,
+ 7, 8,
+ des_encrypt,
+ des_decrypt,
+ des_cbc_mac,
+ krb5int_des_init_state,
+ krb5int_default_free_state
+};
diff --git a/src/lib/crypto/builtin/enc_provider/des3.c b/src/lib/crypto/builtin/enc_provider/des3.c
new file mode 100644
index 000000000000..9b82442236f8
--- /dev/null
+++ b/src/lib/crypto/builtin/enc_provider/des3.c
@@ -0,0 +1,105 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "crypto_int.h"
+#include "des_int.h"
+
+static krb5_error_code
+validate_and_schedule(krb5_key key, const krb5_data *ivec,
+ const krb5_crypto_iov *data, size_t num_data,
+ mit_des3_key_schedule *schedule)
+{
+ if (key->keyblock.length != 24)
+ return(KRB5_BAD_KEYSIZE);
+ if (iov_total_length(data, num_data, FALSE) % 8 != 0)
+ return(KRB5_BAD_MSIZE);
+ if (ivec && (ivec->length != 8))
+ return(KRB5_BAD_MSIZE);
+
+ switch (mit_des3_key_sched(*(mit_des3_cblock *)key->keyblock.contents,
+ *schedule)) {
+ case -1:
+ return(KRB5DES_BAD_KEYPAR);
+ case -2:
+ return(KRB5DES_WEAK_KEY);
+ }
+ return 0;
+}
+
+static krb5_error_code
+k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+ size_t num_data)
+{
+ mit_des3_key_schedule schedule;
+ krb5_error_code err;
+
+ err = validate_and_schedule(key, ivec, data, num_data, &schedule);
+ if (err)
+ return err;
+
+ /* this has a return value, but the code always returns zero */
+ krb5int_des3_cbc_encrypt(data, num_data,
+ schedule[0], schedule[1], schedule[2],
+ ivec != NULL ? (unsigned char *) ivec->data :
+ NULL);
+
+ zap(schedule, sizeof(schedule));
+
+ return(0);
+}
+
+static krb5_error_code
+k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+ size_t num_data)
+{
+ mit_des3_key_schedule schedule;
+ krb5_error_code err;
+
+ err = validate_and_schedule(key, ivec, data, num_data, &schedule);
+ if (err)
+ return err;
+
+ /* this has a return value, but the code always returns zero */
+ krb5int_des3_cbc_decrypt(data, num_data,
+ schedule[0], schedule[1], schedule[2],
+ ivec != NULL ? (unsigned char *) ivec->data :
+ NULL);
+
+ zap(schedule, sizeof(schedule));
+
+ return 0;
+}
+
+const struct krb5_enc_provider krb5int_enc_des3 = {
+ 8,
+ 21, 24,
+ k5_des3_encrypt,
+ k5_des3_decrypt,
+ NULL,
+ krb5int_des_init_state,
+ krb5int_default_free_state
+};
diff --git a/src/lib/crypto/builtin/enc_provider/rc4.c b/src/lib/crypto/builtin/enc_provider/rc4.c
new file mode 100644
index 000000000000..3776f80715ab
--- /dev/null
+++ b/src/lib/crypto/builtin/enc_provider/rc4.c
@@ -0,0 +1,190 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/enc_provider/rc4.c */
+/*
+ * Copyright (c) 2000 by Computer Science Laboratory,
+ * Rensselaer Polytechnic Institute
+ *
+ * #include STD_DISCLAIMER
+ */
+
+#include "crypto_int.h"
+
+typedef struct
+{
+ unsigned int x;
+ unsigned int y;
+ unsigned char state[256];
+} ArcfourContext;
+
+typedef struct {
+ int initialized;
+ ArcfourContext ctx;
+} ArcFourCipherState;
+
+/* gets the next byte from the PRNG */
+#if ((__GNUC__ >= 2) )
+static __inline__ unsigned int k5_arcfour_byte(ArcfourContext *);
+#else
+static unsigned int k5_arcfour_byte(ArcfourContext *);
+#endif /* gcc inlines*/
+
+/* Initializes the context and sets the key. */
+static krb5_error_code k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key,
+ unsigned int keylen);
+
+/* Encrypts/decrypts data. */
+static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest,
+ const unsigned char *src, unsigned int len);
+
+static inline unsigned int k5_arcfour_byte(ArcfourContext * ctx)
+{
+ unsigned int x;
+ unsigned int y;
+ unsigned int sx, sy;
+ unsigned char *state;
+
+ state = ctx->state;
+ x = (ctx->x + 1) & 0xff;
+ sx = state[x];
+ y = (sx + ctx->y) & 0xff;
+ sy = state[y];
+ ctx->x = x;
+ ctx->y = y;
+ state[y] = sx;
+ state[x] = sy;
+ return state[(sx + sy) & 0xff];
+}
+
+static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest,
+ const unsigned char *src, unsigned int len)
+{
+ unsigned int i;
+ for (i = 0; i < len; i++)
+ dest[i] = src[i] ^ k5_arcfour_byte(ctx);
+}
+
+
+static krb5_error_code
+k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key,
+ unsigned int key_len)
+{
+ unsigned int t, u;
+ unsigned int keyindex;
+ unsigned int stateindex;
+ unsigned char* state;
+ unsigned int counter;
+
+ if (key_len != 16)
+ return KRB5_BAD_MSIZE; /*this is probably not the correct error code
+ to return */
+ state = &ctx->state[0];
+ ctx->x = 0;
+ ctx->y = 0;
+ for (counter = 0; counter < 256; counter++)
+ state[counter] = counter;
+ keyindex = 0;
+ stateindex = 0;
+ for (counter = 0; counter < 256; counter++)
+ {
+ t = state[counter];
+ stateindex = (stateindex + key[keyindex] + t) & 0xff;
+ u = state[stateindex];
+ state[stateindex] = t;
+ state[counter] = u;
+ if (++keyindex >= key_len)
+ keyindex = 0;
+ }
+ return 0;
+}
+
+
+static krb5_error_code
+k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
+ size_t num_data)
+{
+ ArcfourContext *arcfour_ctx = NULL;
+ ArcFourCipherState *cipher_state = NULL;
+ krb5_error_code ret;
+ size_t i;
+
+ if (key->keyblock.length != 16)
+ return KRB5_BAD_KEYSIZE;
+ if (state != NULL && (state->length != sizeof(ArcFourCipherState)))
+ return KRB5_BAD_MSIZE;
+
+ if (state != NULL) {
+ cipher_state = (ArcFourCipherState *)state->data;
+ arcfour_ctx = &cipher_state->ctx;
+ if (cipher_state->initialized == 0) {
+ ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents,
+ key->keyblock.length);
+ if (ret != 0)
+ return ret;
+
+ cipher_state->initialized = 1;
+ }
+ } else {
+ arcfour_ctx = (ArcfourContext *)malloc(sizeof(ArcfourContext));
+ if (arcfour_ctx == NULL)
+ return ENOMEM;
+
+ ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents,
+ key->keyblock.length);
+ if (ret != 0) {
+ free(arcfour_ctx);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < num_data; i++) {
+ krb5_crypto_iov *iov = &data[i];
+
+ if (ENCRYPT_IOV(iov))
+ k5_arcfour_crypt(arcfour_ctx, (unsigned char *)iov->data.data,
+ (const unsigned char *)iov->data.data, iov->data.length);
+ }
+
+ if (state == NULL)
+ zapfree(arcfour_ctx, sizeof(ArcfourContext));
+
+ return 0;
+}
+
+static krb5_error_code
+k5_arcfour_init_state (const krb5_keyblock *key,
+ krb5_keyusage keyusage, krb5_data *new_state)
+{
+ /* Note that we can't actually set up the state here because the key
+ * will change between now and when encrypt is called
+ * because it is data dependent. Yeah, this has strange
+ * properties. --SDH
+ */
+ new_state->length = sizeof (ArcFourCipherState);
+ new_state->data = malloc (new_state->length);
+ if (new_state->data) {
+ memset (new_state->data, 0 , new_state->length);
+ /* That will set initialized to zero*/
+ }else {
+ return (ENOMEM);
+ }
+ return 0;
+}
+
+/* Since the arcfour cipher is identical going forwards and backwards,
+ we just call "docrypt" directly
+*/
+const struct krb5_enc_provider krb5int_enc_arcfour = {
+ /* This seems to work... although I am not sure what the
+ implications are in other places in the kerberos library */
+ 1,
+ /* Keysize is arbitrary in arcfour, but the constraints of the
+ system, and to attempt to work with the MSFT system forces us
+ to 16byte/128bit. Since there is no parity in the key, the
+ byte and length are the same. */
+ 16, 16,
+ k5_arcfour_docrypt,
+ k5_arcfour_docrypt,
+ NULL,
+ k5_arcfour_init_state, /*xxx not implemented yet*/
+ krb5int_default_free_state
+};
diff --git a/src/lib/crypto/builtin/hash_provider/Makefile.in b/src/lib/crypto/builtin/hash_provider/Makefile.in
new file mode 100644
index 000000000000..2f587a497a72
--- /dev/null
+++ b/src/lib/crypto/builtin/hash_provider/Makefile.in
@@ -0,0 +1,40 @@
+mydir=lib$(S)crypto$(S)builtin$(S)hash_provider
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../krb -I$(srcdir)/../md4 \
+ -I$(srcdir)/../md5 -I$(srcdir)/../sha1 -I$(srcdir)/../sha2
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR = builtin\hash_provider
+##DOS##OBJFILE = ..\..\$(OUTPRE)hash_provider.lst
+
+STLIBOBJS= \
+ hash_crc32.o \
+ hash_md4.o \
+ hash_md5.o \
+ hash_sha1.o \
+ hash_sha2.o
+
+OBJS= $(OUTPRE)hash_crc32.$(OBJEXT) \
+ $(OUTPRE)hash_md4.$(OBJEXT) \
+ $(OUTPRE)hash_md5.$(OBJEXT) \
+ $(OUTPRE)hash_sha1.$(OBJEXT) \
+ $(OUTPRE)hash_sha2.$(OBJEXT)
+
+SRCS= $(srcdir)/hash_crc32.c \
+ $(srcdir)/hash_md4.c \
+ $(srcdir)/hash_md5.c \
+ $(srcdir)/hash_sha1.c \
+ $(srcdir)/hash_sha2.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix: all-libobjs
+
+includes: depend
+
+depend: $(SRCS)
+
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/hash_provider/deps b/src/lib/crypto/builtin/hash_provider/deps
new file mode 100644
index 000000000000..18f89b383cea
--- /dev/null
+++ b/src/lib/crypto/builtin/hash_provider/deps
@@ -0,0 +1,68 @@
+#
+# Generated makefile dependencies follow.
+#
+hash_crc32.so hash_crc32.po $(OUTPRE)hash_crc32.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../aes/aes.h \
+ $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ hash_crc32.c
+hash_md4.so hash_md4.po $(OUTPRE)hash_md4.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../aes/aes.h \
+ $(srcdir)/../crypto_mod.h $(srcdir)/../md4/rsa-md4.h \
+ $(srcdir)/../sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h hash_md4.c
+hash_md5.so hash_md5.po $(OUTPRE)hash_md5.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../aes/aes.h \
+ $(srcdir)/../crypto_mod.h $(srcdir)/../md5/rsa-md5.h \
+ $(srcdir)/../sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h hash_md5.c
+hash_sha1.so hash_sha1.po $(OUTPRE)hash_sha1.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../aes/aes.h \
+ $(srcdir)/../crypto_mod.h $(srcdir)/../sha1/shs.h $(srcdir)/../sha2/sha2.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ hash_sha1.c
+hash_sha2.so hash_sha2.po $(OUTPRE)hash_sha2.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../aes/aes.h \
+ $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ hash_sha2.c
diff --git a/src/lib/crypto/builtin/hash_provider/hash_crc32.c b/src/lib/crypto/builtin/hash_provider/hash_crc32.c
new file mode 100644
index 000000000000..1d0be55637a9
--- /dev/null
+++ b/src/lib/crypto/builtin/hash_provider/hash_crc32.c
@@ -0,0 +1,56 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "crypto_int.h"
+
+static krb5_error_code
+k5_crc32_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+{
+ unsigned long c;
+ unsigned int i;
+
+ if (output->length != CRC32_CKSUM_LENGTH)
+ return KRB5_CRYPTO_INTERNAL;
+
+ c = 0;
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov))
+ mit_crc32(iov->data.data, iov->data.length, &c);
+ }
+
+ store_32_le(c, output->data);
+ return 0;
+}
+
+const struct krb5_hash_provider krb5int_hash_crc32 = {
+ "CRC32",
+ CRC32_CKSUM_LENGTH,
+ 1,
+ k5_crc32_hash
+};
diff --git a/src/lib/crypto/builtin/hash_provider/hash_md4.c b/src/lib/crypto/builtin/hash_provider/hash_md4.c
new file mode 100644
index 000000000000..e7daf5277622
--- /dev/null
+++ b/src/lib/crypto/builtin/hash_provider/hash_md4.c
@@ -0,0 +1,61 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "crypto_int.h"
+#include "rsa-md4.h"
+
+static krb5_error_code
+k5_md4_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+{
+ krb5_MD4_CTX ctx;
+ unsigned int i;
+
+ if (output->length != RSA_MD4_CKSUM_LENGTH)
+ return(KRB5_CRYPTO_INTERNAL);
+
+ krb5int_MD4Init(&ctx);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov)) {
+ krb5int_MD4Update(&ctx, (unsigned char *) iov->data.data,
+ iov->data.length);
+ }
+ }
+ krb5int_MD4Final(&ctx);
+
+ memcpy(output->data, ctx.digest, RSA_MD4_CKSUM_LENGTH);
+
+ return(0);
+}
+
+const struct krb5_hash_provider krb5int_hash_md4 = {
+ "MD4",
+ RSA_MD4_CKSUM_LENGTH,
+ 64,
+ k5_md4_hash
+};
diff --git a/src/lib/crypto/builtin/hash_provider/hash_md5.c b/src/lib/crypto/builtin/hash_provider/hash_md5.c
new file mode 100644
index 000000000000..0f655ddae85c
--- /dev/null
+++ b/src/lib/crypto/builtin/hash_provider/hash_md5.c
@@ -0,0 +1,61 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "crypto_int.h"
+#include "rsa-md5.h"
+
+static krb5_error_code
+k5_md5_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+{
+ krb5_MD5_CTX ctx;
+ unsigned int i;
+
+ if (output->length != RSA_MD5_CKSUM_LENGTH)
+ return KRB5_CRYPTO_INTERNAL;
+
+ krb5int_MD5Init(&ctx);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov)) {
+ krb5int_MD5Update(&ctx, (unsigned char *) iov->data.data,
+ iov->data.length);
+ }
+ }
+ krb5int_MD5Final(&ctx);
+
+ memcpy(output->data, ctx.digest, RSA_MD5_CKSUM_LENGTH);
+
+ return 0;
+}
+
+const struct krb5_hash_provider krb5int_hash_md5 = {
+ "MD5",
+ RSA_MD5_CKSUM_LENGTH,
+ 64,
+ k5_md5_hash
+};
diff --git a/src/lib/crypto/builtin/hash_provider/hash_sha1.c b/src/lib/crypto/builtin/hash_provider/hash_sha1.c
new file mode 100644
index 000000000000..535e8e584a95
--- /dev/null
+++ b/src/lib/crypto/builtin/hash_provider/hash_sha1.c
@@ -0,0 +1,62 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "crypto_int.h"
+#include "shs.h"
+
+static krb5_error_code
+k5_sha1_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+{
+ SHS_INFO ctx;
+ unsigned int i;
+
+ if (output->length != SHS_DIGESTSIZE)
+ return KRB5_CRYPTO_INTERNAL;
+
+ shsInit(&ctx);
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (SIGN_IOV(iov)) {
+ shsUpdate(&ctx, (unsigned char *) iov->data.data,
+ iov->data.length);
+ }
+ }
+ shsFinal(&ctx);
+
+ for (i = 0; i < sizeof(ctx.digest) / sizeof(ctx.digest[0]); i++)
+ store_32_be(ctx.digest[i], &output->data[i*4]);
+
+ return 0;
+}
+
+const struct krb5_hash_provider krb5int_hash_sha1 = {
+ "SHA1",
+ SHS_DIGESTSIZE,
+ SHS_DATASIZE,
+ k5_sha1_hash
+};
diff --git a/src/lib/crypto/builtin/hash_provider/hash_sha2.c b/src/lib/crypto/builtin/hash_provider/hash_sha2.c
new file mode 100644
index 000000000000..ac4896d80e43
--- /dev/null
+++ b/src/lib/crypto/builtin/hash_provider/hash_sha2.c
@@ -0,0 +1,88 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/hash_provider/sha2.c - SHA-2 hash providers */
+/*
+ * Copyright (C) 2015 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "crypto_int.h"
+#include "sha2.h"
+
+static krb5_error_code
+k5_sha256_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+{
+ SHA256_CTX ctx;
+ size_t i;
+ const krb5_crypto_iov *iov;
+
+ if (output->length != SHA256_DIGEST_LENGTH)
+ return KRB5_CRYPTO_INTERNAL;
+
+ k5_sha256_init(&ctx);
+ for (i = 0; i < num_data; i++) {
+ iov = &data[i];
+ if (SIGN_IOV(iov))
+ k5_sha256_update(&ctx, iov->data.data, iov->data.length);
+ }
+ k5_sha256_final(output->data, &ctx);
+ return 0;
+}
+
+static krb5_error_code
+k5_sha384_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+{
+ SHA384_CTX ctx;
+ size_t i;
+ const krb5_crypto_iov *iov;
+
+ if (output->length != SHA384_DIGEST_LENGTH)
+ return KRB5_CRYPTO_INTERNAL;
+
+ k5_sha384_init(&ctx);
+ for (i = 0; i < num_data; i++) {
+ iov = &data[i];
+ if (SIGN_IOV(iov))
+ k5_sha384_update(&ctx, iov->data.data, iov->data.length);
+ }
+ k5_sha384_final(output->data, &ctx);
+ return 0;
+}
+
+const struct krb5_hash_provider krb5int_hash_sha256 = {
+ "SHA-256",
+ SHA256_DIGEST_LENGTH,
+ SHA256_BLOCK_SIZE,
+ k5_sha256_hash
+};
+
+const struct krb5_hash_provider krb5int_hash_sha384 = {
+ "SHA-384",
+ SHA384_DIGEST_LENGTH,
+ SHA384_BLOCK_SIZE,
+ k5_sha384_hash
+};
diff --git a/src/lib/crypto/builtin/hmac.c b/src/lib/crypto/builtin/hmac.c
new file mode 100644
index 000000000000..95c8f5f4a0ea
--- /dev/null
+++ b/src/lib/crypto/builtin/hmac.c
@@ -0,0 +1,120 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "crypto_int.h"
+
+/*
+ * Because our built-in HMAC implementation doesn't need to invoke any
+ * encryption or keyed hash functions, it is simplest to define it in terms of
+ * keyblocks, and then supply a simple wrapper for the "normal" krb5_key-using
+ * interfaces. The keyblock interfaces are useful for code which creates
+ * intermediate keyblocks.
+ */
+
+/*
+ * The HMAC transform looks like:
+ *
+ * H(K XOR opad, H(K XOR ipad, text))
+ *
+ * where H is a cryptographic hash
+ * K is an n byte key
+ * ipad is the byte 0x36 repeated blocksize times
+ * opad is the byte 0x5c repeated blocksize times
+ * and text is the data being protected
+ */
+
+krb5_error_code
+krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
+ const krb5_keyblock *keyblock,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ unsigned char *xorkey = NULL, *ihash = NULL;
+ unsigned int i;
+ krb5_crypto_iov *ihash_iov = NULL, ohash_iov[2];
+ krb5_data hashout;
+ krb5_error_code ret;
+
+ if (keyblock->length > hash->blocksize)
+ return KRB5_CRYPTO_INTERNAL;
+ if (output->length < hash->hashsize)
+ return KRB5_BAD_MSIZE;
+
+ /* Allocate space for the xor key, hash input vector, and inner hash */
+ xorkey = k5alloc(hash->blocksize, &ret);
+ if (xorkey == NULL)
+ goto cleanup;
+ ihash = k5alloc(hash->hashsize, &ret);
+ if (ihash == NULL)
+ goto cleanup;
+ ihash_iov = k5calloc(num_data + 1, sizeof(krb5_crypto_iov), &ret);
+ if (ihash_iov == NULL)
+ goto cleanup;
+
+ /* Create the inner padded key. */
+ memset(xorkey, 0x36, hash->blocksize);
+ for (i = 0; i < keyblock->length; i++)
+ xorkey[i] ^= keyblock->contents[i];
+
+ /* Compute the inner hash over the inner key and input data. */
+ ihash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ ihash_iov[0].data = make_data(xorkey, hash->blocksize);
+ memcpy(ihash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
+ hashout = make_data(ihash, hash->hashsize);
+ ret = hash->hash(ihash_iov, num_data + 1, &hashout);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Create the outer padded key. */
+ memset(xorkey, 0x5c, hash->blocksize);
+ for (i = 0; i < keyblock->length; i++)
+ xorkey[i] ^= keyblock->contents[i];
+
+ /* Compute the outer hash over the outer key and inner hash value. */
+ ohash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ ohash_iov[0].data = make_data(xorkey, hash->blocksize);
+ ohash_iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
+ ohash_iov[1].data = make_data(ihash, hash->hashsize);
+ output->length = hash->hashsize;
+ ret = hash->hash(ohash_iov, 2, output);
+ if (ret != 0)
+ memset(output->data, 0, output->length);
+
+cleanup:
+ zapfree(xorkey, hash->blocksize);
+ zapfree(ihash, hash->hashsize);
+ free(ihash_iov);
+ return ret;
+}
+
+krb5_error_code
+krb5int_hmac(const struct krb5_hash_provider *hash, krb5_key key,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ return krb5int_hmac_keyblock(hash, &key->keyblock, data, num_data, output);
+}
diff --git a/src/lib/crypto/builtin/init.c b/src/lib/crypto/builtin/init.c
new file mode 100644
index 000000000000..b88d5deafa71
--- /dev/null
+++ b/src/lib/crypto/builtin/init.c
@@ -0,0 +1,38 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/init.c - Module init and cleanup functions */
+/*
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "crypto_int.h"
+
+int
+krb5int_crypto_impl_init(void)
+{
+ return 0;
+}
+
+void
+krb5int_crypto_impl_cleanup(void)
+{
+}
diff --git a/src/lib/crypto/builtin/md4/ISSUES b/src/lib/crypto/builtin/md4/ISSUES
new file mode 100644
index 000000000000..c343d290269d
--- /dev/null
+++ b/src/lib/crypto/builtin/md4/ISSUES
@@ -0,0 +1,4 @@
+Issues to be addressed for src/lib/crypto/md4: -*- text -*-
+
+
+Assumes int is >= 32 bits.
diff --git a/src/lib/crypto/builtin/md4/Makefile.in b/src/lib/crypto/builtin/md4/Makefile.in
new file mode 100644
index 000000000000..9eb596521db5
--- /dev/null
+++ b/src/lib/crypto/builtin/md4/Makefile.in
@@ -0,0 +1,33 @@
+mydir=lib$(S)crypto$(S)builtin$(S)md4
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+LOCALINCLUDES = -I$(srcdir)
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR = builtin\md4
+##DOS##OBJFILE = ..\..\$(OUTPRE)md4.lst
+
+STLIBOBJS= md4.o
+
+OBJS= $(OUTPRE)md4.$(OBJEXT)
+
+SRCS= $(srcdir)/md4.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix: all-libobjs
+
+includes: depend
+
+depend: $(SRCS)
+
+
+check-unix:
+
+check-windows:
+
+clean:
+
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/md4/deps b/src/lib/crypto/builtin/md4/deps
new file mode 100644
index 000000000000..55d209b453d6
--- /dev/null
+++ b/src/lib/crypto/builtin/md4/deps
@@ -0,0 +1,13 @@
+#
+# Generated makefile dependencies follow.
+#
+md4.so md4.po $(OUTPRE)md4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h md4.c rsa-md4.h
diff --git a/src/lib/crypto/builtin/md4/md4.c b/src/lib/crypto/builtin/md4/md4.c
new file mode 100644
index 000000000000..27d2ad514899
--- /dev/null
+++ b/src/lib/crypto/builtin/md4/md4.c
@@ -0,0 +1,243 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/md4/md4.c */
+
+/*
+ * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
+ *
+ * License to copy and use this software is granted provided that
+ * it is identified as the "RSA Data Security, Inc. MD4 Message
+ * Digest Algorithm" in all material mentioning or referencing this
+ * software or this function.
+ *
+ * License is also granted to make and use derivative works
+ * provided that such works are identified as "derived from the RSA
+ * Data Security, Inc. MD4 Message Digest Algorithm" in all
+ * material mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning
+ * either the merchantability of this software or the suitability
+ * of this software for any particular purpose. It is provided "as
+ * is" without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+/*
+**********************************************************************
+** md4.c **
+** RSA Data Security, Inc. MD4 Message Digest Algorithm **
+** Created: 2/17/90 RLR **
+** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
+**********************************************************************
+*/
+
+#include "k5-int.h"
+#include "rsa-md4.h"
+
+/* forward declaration */
+static void Transform (krb5_ui_4 *, krb5_ui_4 *);
+
+static const unsigned char PADDING[64] = {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* F, G and H are basic MD4 functions: selection, majority, parity */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n))))
+
+/* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s) \
+ {(a) += F ((b), (c), (d)) + (x); \
+ (a) &= 0xffffffff; \
+ (a) = ROTATE_LEFT ((a), (s));}
+#define GG(a, b, c, d, x, s) \
+ {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \
+ (a) &= 0xffffffff; \
+ (a) = ROTATE_LEFT ((a), (s));}
+#define HH(a, b, c, d, x, s) \
+ {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \
+ (a) &= 0xffffffff; \
+ (a) = ROTATE_LEFT ((a), (s));}
+
+void
+krb5int_MD4Init (krb5_MD4_CTX *mdContext)
+{
+ mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0;
+
+ /* Load magic initialization constants.
+ */
+ mdContext->buf[0] = 0x67452301UL;
+ mdContext->buf[1] = 0xefcdab89UL;
+ mdContext->buf[2] = 0x98badcfeUL;
+ mdContext->buf[3] = 0x10325476UL;
+}
+
+void
+krb5int_MD4Update (krb5_MD4_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen)
+{
+ krb5_ui_4 in[16];
+ int mdi;
+ unsigned int i, ii;
+
+ /* compute number of bytes mod 64 */
+ mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+ /* update number of bits */
+ if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0])
+ mdContext->i[1]++;
+ mdContext->i[0] += ((krb5_ui_4)inLen << 3);
+ mdContext->i[1] += ((krb5_ui_4)inLen >> 29);
+
+ while (inLen--) {
+ /* add new character to buffer, increment mdi */
+ mdContext->in[mdi++] = *inBuf++;
+
+ /* transform if necessary */
+ if (mdi == 0x40) {
+ for (i = 0, ii = 0; i < 16; i++, ii += 4) {
+ in[i] = load_32_le(mdContext->in+ii);
+ }
+ Transform (mdContext->buf, in);
+ mdi = 0;
+ }
+ }
+}
+
+void
+krb5int_MD4Final (krb5_MD4_CTX *mdContext)
+{
+ krb5_ui_4 in[16];
+ int mdi;
+ unsigned int i, ii;
+ unsigned int padLen;
+
+ /* save number of bits */
+ in[14] = mdContext->i[0];
+ in[15] = mdContext->i[1];
+
+ /* compute number of bytes mod 64 */
+ mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+ /* pad out to 56 mod 64 */
+ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+ krb5int_MD4Update (mdContext, PADDING, padLen);
+
+ /* append length in bits and transform */
+ for (i = 0, ii = 0; i < 14; i++, ii += 4)
+ in[i] = load_32_le(mdContext->in+ii);
+ Transform (mdContext->buf, in);
+
+
+ /* store buffer in digest */
+ for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+ store_32_le(mdContext->buf[i], mdContext->digest+ii);
+ }
+}
+
+/* Basic MD4 step. Transform buf based on in.
+ */
+static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in)
+{
+ register krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+#if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
+ int i;
+#define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; }
+ for (i = 0; i < 16; i++) {
+ static const unsigned char round1consts[] = { 3, 7, 11, 19, };
+ FF (a, b, c, d, in[i], round1consts[i%4]); ROTATE;
+ }
+ for (i = 0; i < 16; i++) {
+ static const unsigned char round2indices[] = {
+ 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15
+ };
+ static const unsigned char round2consts[] = { 3, 5, 9, 13 };
+ GG (a, b, c, d, in[round2indices[i]], round2consts[i%4]); ROTATE;
+ }
+ for (i = 0; i < 16; i++) {
+ static const unsigned char round3indices[] = {
+ 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
+ };
+ static const unsigned char round3consts[] = { 3, 9, 11, 15 };
+ HH (a, b, c, d, in[round3indices[i]], round3consts[i%4]); ROTATE;
+ }
+#else
+ /* Round 1 */
+ FF (a, b, c, d, in[ 0], 3);
+ FF (d, a, b, c, in[ 1], 7);
+ FF (c, d, a, b, in[ 2], 11);
+ FF (b, c, d, a, in[ 3], 19);
+ FF (a, b, c, d, in[ 4], 3);
+ FF (d, a, b, c, in[ 5], 7);
+ FF (c, d, a, b, in[ 6], 11);
+ FF (b, c, d, a, in[ 7], 19);
+ FF (a, b, c, d, in[ 8], 3);
+ FF (d, a, b, c, in[ 9], 7);
+ FF (c, d, a, b, in[10], 11);
+ FF (b, c, d, a, in[11], 19);
+ FF (a, b, c, d, in[12], 3);
+ FF (d, a, b, c, in[13], 7);
+ FF (c, d, a, b, in[14], 11);
+ FF (b, c, d, a, in[15], 19);
+
+ /* Round 2 */
+ GG (a, b, c, d, in[ 0], 3);
+ GG (d, a, b, c, in[ 4], 5);
+ GG (c, d, a, b, in[ 8], 9);
+ GG (b, c, d, a, in[12], 13);
+ GG (a, b, c, d, in[ 1], 3);
+ GG (d, a, b, c, in[ 5], 5);
+ GG (c, d, a, b, in[ 9], 9);
+ GG (b, c, d, a, in[13], 13);
+ GG (a, b, c, d, in[ 2], 3);
+ GG (d, a, b, c, in[ 6], 5);
+ GG (c, d, a, b, in[10], 9);
+ GG (b, c, d, a, in[14], 13);
+ GG (a, b, c, d, in[ 3], 3);
+ GG (d, a, b, c, in[ 7], 5);
+ GG (c, d, a, b, in[11], 9);
+ GG (b, c, d, a, in[15], 13);
+
+ /* Round 3 */
+ HH (a, b, c, d, in[ 0], 3);
+ HH (d, a, b, c, in[ 8], 9);
+ HH (c, d, a, b, in[ 4], 11);
+ HH (b, c, d, a, in[12], 15);
+ HH (a, b, c, d, in[ 2], 3);
+ HH (d, a, b, c, in[10], 9);
+ HH (c, d, a, b, in[ 6], 11);
+ HH (b, c, d, a, in[14], 15);
+ HH (a, b, c, d, in[ 1], 3);
+ HH (d, a, b, c, in[ 9], 9);
+ HH (c, d, a, b, in[ 5], 11);
+ HH (b, c, d, a, in[13], 15);
+ HH (a, b, c, d, in[ 3], 3);
+ HH (d, a, b, c, in[11], 9);
+ HH (c, d, a, b, in[ 7], 11);
+ HH (b, c, d, a, in[15], 15);
+#endif
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+/*
+**********************************************************************
+** End of md4.c **
+******************************* (cut) ********************************
+*/
diff --git a/src/lib/crypto/builtin/md4/rsa-md4.h b/src/lib/crypto/builtin/md4/rsa-md4.h
new file mode 100644
index 000000000000..c404e151b9cd
--- /dev/null
+++ b/src/lib/crypto/builtin/md4/rsa-md4.h
@@ -0,0 +1,90 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/md4/rsa-md4.h */
+/*
+ * Copyright 1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+/*
+ * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
+ *
+ * License to copy and use this software is granted provided that
+ * it is identified as the "RSA Data Security, Inc. MD4 Message
+ * Digest Algorithm" in all material mentioning or referencing this
+ * software or this function.
+ *
+ * License is also granted to make and use derivative works
+ * provided that such works are identified as "derived from the RSA
+ * Data Security, Inc. MD4 Message Digest Algorithm" in all
+ * material mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning
+ * either the merchantability of this software or the suitability
+ * of this software for any particular purpose. It is provided "as
+ * is" without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+/* RSA MD4 header file, with Kerberos/STDC additions. */
+
+#ifndef __KRB5_RSA_MD4_H__
+#define __KRB5_RSA_MD4_H__
+
+#ifdef unicos61
+#include <sys/types.h>
+#endif /* unicos61 */
+
+/* 16 u_char's in the digest */
+#define RSA_MD4_CKSUM_LENGTH 16
+/* des blocksize is 8, so this works nicely... */
+#define OLD_RSA_MD4_DES_CKSUM_LENGTH 16
+#define NEW_RSA_MD4_DES_CKSUM_LENGTH 24
+#define RSA_MD4_DES_CONFOUND_LENGTH 8
+
+/*
+**********************************************************************
+** md4.h -- Header file for implementation of MD4 **
+** RSA Data Security, Inc. MD4 Message Digest Algorithm **
+** Created: 2/17/90 RLR **
+** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
+**********************************************************************
+*/
+
+/* Data structure for MD4 (Message Digest) computation */
+typedef struct {
+ krb5_ui_4 i[2]; /* number of _bits_ handled mod 2^64 */
+ krb5_ui_4 buf[4]; /* scratch buffer */
+ unsigned char in[64]; /* input buffer */
+ unsigned char digest[16]; /* actual digest after MD4Final call */
+} krb5_MD4_CTX;
+
+extern void krb5int_MD4Init(krb5_MD4_CTX *);
+extern void krb5int_MD4Update(krb5_MD4_CTX *, const unsigned char *, unsigned int);
+extern void krb5int_MD4Final(krb5_MD4_CTX *);
+
+/*
+**********************************************************************
+** End of md4.h **
+******************************* (cut) ********************************
+*/
+#endif /* __KRB5_RSA_MD4_H__ */
diff --git a/src/lib/crypto/builtin/md5/ISSUES b/src/lib/crypto/builtin/md5/ISSUES
new file mode 100644
index 000000000000..631238adfb04
--- /dev/null
+++ b/src/lib/crypto/builtin/md5/ISSUES
@@ -0,0 +1,4 @@
+Issues to be addressed for src/lib/crypto/md5: -*- text -*-
+
+
+Assumes int is >= 32 bits.
diff --git a/src/lib/crypto/builtin/md5/Makefile.in b/src/lib/crypto/builtin/md5/Makefile.in
new file mode 100644
index 000000000000..e8778f380ca3
--- /dev/null
+++ b/src/lib/crypto/builtin/md5/Makefile.in
@@ -0,0 +1,31 @@
+mydir=lib$(S)crypto$(S)builtin$(S)md5
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR = builtin\md5
+##DOS##OBJFILE = ..\..\$(OUTPRE)md5.lst
+
+STLIBOBJS= md5.o
+
+OBJS= $(OUTPRE)md5.$(OBJEXT)
+
+SRCS= $(srcdir)/md5.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix: all-libobjs
+
+includes: depend
+
+depend: $(SRCS)
+
+check-unix:
+
+check-windows:
+
+clean:
+
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/md5/deps b/src/lib/crypto/builtin/md5/deps
new file mode 100644
index 000000000000..31840880f3a2
--- /dev/null
+++ b/src/lib/crypto/builtin/md5/deps
@@ -0,0 +1,13 @@
+#
+# Generated makefile dependencies follow.
+#
+md5.so md5.po $(OUTPRE)md5.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h md5.c rsa-md5.h
diff --git a/src/lib/crypto/builtin/md5/md5.c b/src/lib/crypto/builtin/md5/md5.c
new file mode 100644
index 000000000000..4a169065cd0d
--- /dev/null
+++ b/src/lib/crypto/builtin/md5/md5.c
@@ -0,0 +1,342 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
+ *
+ * License to copy and use this software is granted provided that
+ * it is identified as the "RSA Data Security, Inc. MD5 Message-
+ * Digest Algorithm" in all material mentioning or referencing this
+ * software or this function.
+ *
+ * License is also granted to make and use derivative works
+ * provided that such works are identified as "derived from the RSA
+ * Data Security, Inc. MD5 Message-Digest Algorithm" in all
+ * material mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning
+ * either the merchantability of this software or the suitability
+ * of this software for any particular purpose. It is provided "as
+ * is" without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+/*
+***********************************************************************
+** md5.c -- the source code for MD5 routines **
+** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
+** Created: 2/17/90 RLR **
+** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
+***********************************************************************
+*/
+
+/*
+ * Modified by John Carr, MIT, to use Kerberos 5 typedefs.
+ */
+
+#include "k5-int.h"
+#include "rsa-md5.h"
+
+/*
+***********************************************************************
+** Message-digest routines: **
+** To form the message digest for a message M **
+** (1) Initialize a context buffer mdContext using krb5int_MD5Init **
+** (2) Call krb5int_MD5Update on mdContext and M **
+** (3) Call krb5int_MD5Final on mdContext **
+** The message digest is now in mdContext->digest[0...15] **
+***********************************************************************
+*/
+
+/* forward declaration */
+static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in);
+
+static const unsigned char PADDING[64] = {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* F, G, H and I are basic MD5 functions */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s, ac) \
+ {(a) += F ((b), (c), (d)) + (x) + (krb5_ui_4)(ac); \
+ (a) &= 0xffffffff; \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ (a) &= 0xffffffff; \
+ }
+#define GG(a, b, c, d, x, s, ac) \
+ {(a) += G ((b), (c), (d)) + (x) + (krb5_ui_4)(ac); \
+ (a) &= 0xffffffff; \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ (a) &= 0xffffffff; \
+ }
+#define HH(a, b, c, d, x, s, ac) \
+ {(a) += H ((b), (c), (d)) + (x) + (krb5_ui_4)(ac); \
+ (a) &= 0xffffffff; \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ (a) &= 0xffffffff; \
+ }
+#define II(a, b, c, d, x, s, ac) \
+ {(a) += I ((b), (c), (d)) + (x) + (krb5_ui_4)(ac); \
+ (a) &= 0xffffffff; \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ (a) &= 0xffffffff; \
+ }
+
+/* The routine krb5int_MD5Init initializes the message-digest context
+ mdContext. All fields are set to zero.
+*/
+void
+krb5int_MD5Init (krb5_MD5_CTX *mdContext)
+{
+ mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0;
+
+ /* Load magic initialization constants.
+ */
+ mdContext->buf[0] = 0x67452301UL;
+ mdContext->buf[1] = 0xefcdab89UL;
+ mdContext->buf[2] = 0x98badcfeUL;
+ mdContext->buf[3] = 0x10325476UL;
+}
+
+/* The routine krb5int_MD5Update updates the message-digest context to
+ account for the presence of each of the characters inBuf[0..inLen-1]
+ in the message whose digest is being computed.
+*/
+void
+krb5int_MD5Update (krb5_MD5_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen)
+{
+ krb5_ui_4 in[16];
+ int mdi;
+ unsigned int i, ii;
+
+ /* compute number of bytes mod 64 */
+ mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+ /* update number of bits */
+ if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0])
+ mdContext->i[1]++;
+ mdContext->i[0] += ((krb5_ui_4)inLen << 3);
+ mdContext->i[1] += ((krb5_ui_4)inLen >> 29);
+
+ while (inLen--) {
+ /* add new character to buffer, increment mdi */
+ mdContext->in[mdi++] = *inBuf++;
+
+ /* transform if necessary */
+ if (mdi == 0x40) {
+ for (i = 0, ii = 0; i < 16; i++, ii += 4)
+ in[i] = load_32_le(mdContext->in+ii);
+ Transform (mdContext->buf, in);
+ mdi = 0;
+ }
+ }
+}
+
+/* The routine krb5int_MD5Final terminates the message-digest computation and
+ ends with the desired message digest in mdContext->digest[0...15].
+*/
+void
+krb5int_MD5Final (krb5_MD5_CTX *mdContext)
+{
+ krb5_ui_4 in[16];
+ int mdi;
+ unsigned int i, ii;
+ unsigned int padLen;
+
+ /* save number of bits */
+ in[14] = mdContext->i[0];
+ in[15] = mdContext->i[1];
+
+ /* compute number of bytes mod 64 */
+ mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+ /* pad out to 56 mod 64 */
+ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+ krb5int_MD5Update (mdContext, PADDING, padLen);
+
+ /* append length in bits and transform */
+ for (i = 0, ii = 0; i < 14; i++, ii += 4)
+ in[i] = load_32_le(mdContext->in+ii);
+ Transform (mdContext->buf, in);
+
+ /* store buffer in digest */
+ for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+ store_32_le(mdContext->buf[i], mdContext->digest+ii);
+ }
+}
+
+/* Basic MD5 step. Transforms buf based on in.
+ */
+static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in)
+{
+ register krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+#if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
+
+ int i;
+#define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; }
+ for (i = 0; i < 16; i++) {
+ const unsigned char round1s[] = { 7, 12, 17, 22 };
+ const krb5_ui_4 round1consts[] = {
+ 3614090360UL, 3905402710UL, 606105819UL, 3250441966UL,
+ 4118548399UL, 1200080426UL, 2821735955UL, 4249261313UL,
+ 1770035416UL, 2336552879UL, 4294925233UL, 2304563134UL,
+ 1804603682UL, 4254626195UL, 2792965006UL, 1236535329UL,
+ };
+ FF (a, b, c, d, in[i], round1s[i%4], round1consts[i]);
+ ROTATE;
+ }
+ for (i = 0; i < 16; i++) {
+ const unsigned char round2s[] = { 5, 9, 14, 20 };
+ const krb5_ui_4 round2consts[] = {
+ 4129170786UL, 3225465664UL, 643717713UL, 3921069994UL,
+ 3593408605UL, 38016083UL, 3634488961UL, 3889429448UL,
+ 568446438UL, 3275163606UL, 4107603335UL, 1163531501UL,
+ 2850285829UL, 4243563512UL, 1735328473UL, 2368359562UL,
+ };
+ int r2index = (1 + i * 5) % 16;
+ GG (a, b, c, d, in[r2index], round2s[i%4], round2consts[i]);
+ ROTATE;
+ }
+ for (i = 0; i < 16; i++) {
+ static const unsigned char round3s[] = { 4, 11, 16, 23 };
+ static const krb5_ui_4 round3consts[] = {
+ 4294588738UL, 2272392833UL, 1839030562UL, 4259657740UL,
+ 2763975236UL, 1272893353UL, 4139469664UL, 3200236656UL,
+ 681279174UL, 3936430074UL, 3572445317UL, 76029189UL,
+ 3654602809UL, 3873151461UL, 530742520UL, 3299628645UL,
+ };
+ int r3index = (5 + i * 3) % 16;
+ HH (a, b, c, d, in[r3index], round3s[i%4], round3consts[i]);
+ ROTATE;
+ }
+ for (i = 0; i < 16; i++) {
+ static const unsigned char round4s[] = { 6, 10, 15, 21 };
+ static const krb5_ui_4 round4consts[] = {
+ 4096336452UL, 1126891415UL, 2878612391UL, 4237533241UL,
+ 1700485571UL, 2399980690UL, 4293915773UL, 2240044497UL,
+ 1873313359UL, 4264355552UL, 2734768916UL, 1309151649UL,
+ 4149444226UL, 3174756917UL, 718787259UL, 3951481745UL,
+ };
+ int r4index = (7 * i) % 16;
+ II (a, b, c, d, in[r4index], round4s[i%4], round4consts[i]);
+ ROTATE;
+ }
+
+#else
+
+ /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+ FF ( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */
+ FF ( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */
+ FF ( c, d, a, b, in[ 2], S13, 606105819UL); /* 3 */
+ FF ( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */
+ FF ( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */
+ FF ( d, a, b, c, in[ 5], S12, 1200080426UL); /* 6 */
+ FF ( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */
+ FF ( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */
+ FF ( a, b, c, d, in[ 8], S11, 1770035416UL); /* 9 */
+ FF ( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */
+ FF ( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */
+ FF ( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */
+ FF ( a, b, c, d, in[12], S11, 1804603682UL); /* 13 */
+ FF ( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */
+ FF ( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */
+ FF ( b, c, d, a, in[15], S14, 1236535329UL); /* 16 */
+
+ /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+ GG ( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */
+ GG ( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */
+ GG ( c, d, a, b, in[11], S23, 643717713UL); /* 19 */
+ GG ( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */
+ GG ( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */
+ GG ( d, a, b, c, in[10], S22, 38016083UL); /* 22 */
+ GG ( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */
+ GG ( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */
+ GG ( a, b, c, d, in[ 9], S21, 568446438UL); /* 25 */
+ GG ( d, a, b, c, in[14], S22, 3275163606UL); /* 26 */
+ GG ( c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */
+ GG ( b, c, d, a, in[ 8], S24, 1163531501UL); /* 28 */
+ GG ( a, b, c, d, in[13], S21, 2850285829UL); /* 29 */
+ GG ( d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */
+ GG ( c, d, a, b, in[ 7], S23, 1735328473UL); /* 31 */
+ GG ( b, c, d, a, in[12], S24, 2368359562UL); /* 32 */
+
+ /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+ HH ( a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */
+ HH ( d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */
+ HH ( c, d, a, b, in[11], S33, 1839030562UL); /* 35 */
+ HH ( b, c, d, a, in[14], S34, 4259657740UL); /* 36 */
+ HH ( a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */
+ HH ( d, a, b, c, in[ 4], S32, 1272893353UL); /* 38 */
+ HH ( c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */
+ HH ( b, c, d, a, in[10], S34, 3200236656UL); /* 40 */
+ HH ( a, b, c, d, in[13], S31, 681279174UL); /* 41 */
+ HH ( d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */
+ HH ( c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */
+ HH ( b, c, d, a, in[ 6], S34, 76029189UL); /* 44 */
+ HH ( a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */
+ HH ( d, a, b, c, in[12], S32, 3873151461UL); /* 46 */
+ HH ( c, d, a, b, in[15], S33, 530742520UL); /* 47 */
+ HH ( b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */
+
+ /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+ II ( a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */
+ II ( d, a, b, c, in[ 7], S42, 1126891415UL); /* 50 */
+ II ( c, d, a, b, in[14], S43, 2878612391UL); /* 51 */
+ II ( b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */
+ II ( a, b, c, d, in[12], S41, 1700485571UL); /* 53 */
+ II ( d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */
+ II ( c, d, a, b, in[10], S43, 4293915773UL); /* 55 */
+ II ( b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */
+ II ( a, b, c, d, in[ 8], S41, 1873313359UL); /* 57 */
+ II ( d, a, b, c, in[15], S42, 4264355552UL); /* 58 */
+ II ( c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */
+ II ( b, c, d, a, in[13], S44, 1309151649UL); /* 60 */
+ II ( a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */
+ II ( d, a, b, c, in[11], S42, 3174756917UL); /* 62 */
+ II ( c, d, a, b, in[ 2], S43, 718787259UL); /* 63 */
+ II ( b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */
+
+#endif /* small? */
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
diff --git a/src/lib/crypto/builtin/md5/rsa-md5.h b/src/lib/crypto/builtin/md5/rsa-md5.h
new file mode 100644
index 000000000000..cbdf67cfb333
--- /dev/null
+++ b/src/lib/crypto/builtin/md5/rsa-md5.h
@@ -0,0 +1,59 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
+ *
+ * License to copy and use this software is granted provided that
+ * it is identified as the "RSA Data Security, Inc. MD5 Message-
+ * Digest Algorithm" in all material mentioning or referencing this
+ * software or this function.
+ *
+ * License is also granted to make and use derivative works
+ * provided that such works are identified as "derived from the RSA
+ * Data Security, Inc. MD5 Message-Digest Algorithm" in all
+ * material mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning
+ * either the merchantability of this software or the suitability
+ * of this software for any particular purpose. It is provided "as
+ * is" without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+/*
+***********************************************************************
+** md5.h -- header file for implementation of MD5 **
+** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
+** Created: 2/17/90 RLR **
+** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
+** Revised (for MD5): RLR 4/27/91 **
+** -- G modified to have y&~z instead of y&z **
+** -- FF, GG, HH modified to add in last register done **
+** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
+** -- distinct additive constant for each step **
+** -- round 4 added, working mod 7 **
+***********************************************************************
+*/
+
+#ifndef KRB5_RSA_MD5__
+#define KRB5_RSA_MD5__
+
+/* Data structure for MD5 (Message-Digest) computation */
+typedef struct {
+ krb5_ui_4 i[2]; /* number of _bits_ handled mod 2^64 */
+ krb5_ui_4 buf[4]; /* scratch buffer */
+ unsigned char in[64]; /* input buffer */
+ unsigned char digest[16]; /* actual digest after MD5Final call */
+} krb5_MD5_CTX;
+
+extern void krb5int_MD5Init(krb5_MD5_CTX *);
+extern void krb5int_MD5Update(krb5_MD5_CTX *,const unsigned char *,unsigned int);
+extern void krb5int_MD5Final(krb5_MD5_CTX *);
+
+#define RSA_MD5_CKSUM_LENGTH 16
+#define OLD_RSA_MD5_DES_CKSUM_LENGTH 16
+#define NEW_RSA_MD5_DES_CKSUM_LENGTH 24
+#define RSA_MD5_DES_CONFOUND_LENGTH 8
+
+#endif /* KRB5_RSA_MD5__ */
diff --git a/src/lib/crypto/builtin/pbkdf2.c b/src/lib/crypto/builtin/pbkdf2.c
new file mode 100644
index 000000000000..d36b32e7e3db
--- /dev/null
+++ b/src/lib/crypto/builtin/pbkdf2.c
@@ -0,0 +1,249 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/builtin/pbkdf2.c - Implementation of PBKDF2 from RFC 2898 */
+/*
+ * Copyright 2002, 2008 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include <ctype.h>
+#include "crypto_int.h"
+
+/*
+ * RFC 2898 specifies PBKDF2 in terms of an underlying pseudo-random
+ * function with two arguments (password and salt||blockindex). Right
+ * now we only use PBKDF2 with the hmac-sha1 PRF, also specified in
+ * RFC 2898, which invokes HMAC with the password as the key and the
+ * second argument as the text. (HMAC accepts any key size up to the
+ * block size; the password is pre-hashed with unkeyed SHA1 if it is
+ * longer than the block size.)
+ *
+ * For efficiency, it is better to generate the key from the password
+ * once at the beginning, so we specify prf_fn in terms of a
+ * krb5_key first argument. That might not be convenient for a PRF
+ * which uses the password in some other way, so this might need to be
+ * adjusted in the future.
+ */
+
+typedef krb5_error_code (*prf_fn)(krb5_key pass, krb5_data *salt,
+ krb5_data *out);
+
+static int debug_hmac = 0;
+
+static void printd (const char *descr, krb5_data *d) {
+ unsigned int i, j;
+ const int r = 16;
+
+ printf("%s:", descr);
+
+ for (i = 0; i < d->length; i += r) {
+ printf("\n %04x: ", i);
+ for (j = i; j < i + r && j < d->length; j++)
+ printf(" %02x", 0xff & d->data[j]);
+ for (; j < i + r; j++)
+ printf(" ");
+ printf(" ");
+ for (j = i; j < i + r && j < d->length; j++) {
+ int c = 0xff & d->data[j];
+ printf("%c", isprint(c) ? c : '.');
+ }
+ }
+ printf("\n");
+}
+
+/*
+ * Implements the hmac-sha1 PRF. pass has been pre-hashed (if
+ * necessary) and converted to a key already; salt has had the block
+ * index appended to the original salt.
+ */
+static krb5_error_code
+hmac(const struct krb5_hash_provider *hash, krb5_keyblock *pass,
+ krb5_data *salt, krb5_data *out)
+{
+ krb5_error_code err;
+ krb5_crypto_iov iov;
+
+ if (debug_hmac)
+ printd(" hmac input", salt);
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *salt;
+ err = krb5int_hmac_keyblock(hash, pass, &iov, 1, out);
+ if (err == 0 && debug_hmac)
+ printd(" hmac output", out);
+ return err;
+}
+
+static krb5_error_code
+F(char *output, char *u_tmp1, char *u_tmp2,
+ const struct krb5_hash_provider *hash, size_t hlen, krb5_keyblock *pass,
+ const krb5_data *salt, unsigned long count, int i)
+{
+ unsigned char ibytes[4];
+ unsigned int j, k;
+ krb5_data sdata;
+ krb5_data out;
+ krb5_error_code err;
+
+#if 0
+ printf("F(i=%d, count=%lu, pass=%d:%s)\n", i, count,
+ pass->length, pass->data);
+#endif
+
+ /* Compute U_1. */
+ store_32_be(i, ibytes);
+
+ memcpy(u_tmp2, salt->data, salt->length);
+ memcpy(u_tmp2 + salt->length, ibytes, 4);
+ sdata = make_data(u_tmp2, salt->length + 4);
+
+#if 0
+ printd("initial salt", &sdata);
+#endif
+
+ out = make_data(u_tmp1, hlen);
+
+#if 0
+ printf("F: computing hmac #1 (U_1) with %s\n", pdata.contents);
+#endif
+ err = hmac(hash, pass, &sdata, &out);
+ if (err)
+ return err;
+#if 0
+ printd("F: prf return value", &out);
+#endif
+ memcpy(output, u_tmp1, hlen);
+
+ /* Compute U_2, .. U_c. */
+ sdata.length = hlen;
+ for (j = 2; j <= count; j++) {
+#if 0
+ printf("F: computing hmac #%d (U_%d)\n", j, j);
+#endif
+ memcpy(u_tmp2, u_tmp1, hlen);
+ err = hmac(hash, pass, &sdata, &out);
+ if (err)
+ return err;
+#if 0
+ printd("F: prf return value", &out);
+#endif
+ /* And xor them together. */
+ for (k = 0; k < hlen; k++)
+ output[k] ^= u_tmp1[k];
+#if 0
+ printf("F: xor result:\n");
+ for (k = 0; k < hlen; k++)
+ printf(" %02x", 0xff & output[k]);
+ printf("\n");
+#endif
+ }
+ return 0;
+}
+
+static krb5_error_code
+pbkdf2(const struct krb5_hash_provider *hash, krb5_keyblock *pass,
+ const krb5_data *salt, unsigned long count, const krb5_data *output)
+{
+ size_t hlen = hash->hashsize;
+ int l, i;
+ char *utmp1, *utmp2;
+ char utmp3[128]; /* XXX length shouldn't be hardcoded! */
+
+ if (output->length == 0 || hlen == 0)
+ abort();
+ /* Step 1 & 2. */
+ if (output->length / hlen > 0xffffffff)
+ abort();
+ /* Step 2. */
+ l = (output->length + hlen - 1) / hlen;
+
+ utmp1 = /*output + dklen; */ malloc(hlen);
+ if (utmp1 == NULL)
+ return ENOMEM;
+ utmp2 = /*utmp1 + hlen; */ malloc(salt->length + 4 + hlen);
+ if (utmp2 == NULL) {
+ free(utmp1);
+ return ENOMEM;
+ }
+
+ /* Step 3. */
+ for (i = 1; i <= l; i++) {
+#if 0
+ int j;
+#endif
+ krb5_error_code err;
+ char *out;
+
+ if (i == l)
+ out = utmp3;
+ else
+ out = output->data + (i-1) * hlen;
+ err = F(out, utmp1, utmp2, hash, hlen, pass, salt, count, i);
+ if (err) {
+ free(utmp1);
+ free(utmp2);
+ return err;
+ }
+ if (i == l)
+ memcpy(output->data + (i-1) * hlen, utmp3,
+ output->length - (i-1) * hlen);
+
+#if 0
+ printf("after F(%d), @%p:\n", i, output->data);
+ for (j = (i-1) * hlen; j < i * hlen; j++)
+ printf(" %02x", 0xff & output->data[j]);
+ printf ("\n");
+#endif
+ }
+ free(utmp1);
+ free(utmp2);
+ return 0;
+}
+
+krb5_error_code
+krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash,
+ const krb5_data *out, unsigned long count,
+ const krb5_data *pass, const krb5_data *salt)
+{
+ krb5_keyblock keyblock;
+ char tmp[128];
+ krb5_data d;
+ krb5_crypto_iov iov;
+ krb5_error_code err;
+
+ assert(hash->hashsize <= sizeof(tmp));
+ if (pass->length > hash->blocksize) {
+ d = make_data(tmp, hash->hashsize);
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *pass;
+ err = hash->hash(&iov, 1, &d);
+ if (err)
+ return err;
+ keyblock.length = d.length;
+ keyblock.contents = (krb5_octet *) d.data;
+ } else {
+ keyblock.length = pass->length;
+ keyblock.contents = (krb5_octet *) pass->data;
+ }
+ keyblock.enctype = ENCTYPE_NULL;
+
+ err = pbkdf2(hash, &keyblock, salt, count, out);
+ return err;
+}
diff --git a/src/lib/crypto/builtin/sha1/ISSUES b/src/lib/crypto/builtin/sha1/ISSUES
new file mode 100644
index 000000000000..c63faf6e7a00
--- /dev/null
+++ b/src/lib/crypto/builtin/sha1/ISSUES
@@ -0,0 +1,8 @@
+Issues to be addressed for src/lib/crypto/sha1: -*- text -*-
+
+
+Assumes int (look for "count") is >= 32 bits.
+
+Changing the types of internal variables is easy, but shsUpdate takes
+an int parameter; changing that could change the ABI on some
+platforms.
diff --git a/src/lib/crypto/builtin/sha1/Makefile.in b/src/lib/crypto/builtin/sha1/Makefile.in
new file mode 100644
index 000000000000..5895c364c65f
--- /dev/null
+++ b/src/lib/crypto/builtin/sha1/Makefile.in
@@ -0,0 +1,44 @@
+mydir=lib$(S)crypto$(S)builtin$(S)sha1
+BUILDTOP=$(REL)..$(S)..$(S)..$(S)..
+
+##DOS##BUILDTOP = ..\..\..\..
+##DOS##PREFIXDIR = builtin\sha1
+##DOS##OBJFILE = ..\..\$(OUTPRE)sha1.lst
+
+STLIBOBJS= shs.o
+
+OBJS= $(OUTPRE)shs.$(OBJEXT)
+
+SRCS= $(srcdir)/shs.c
+
+##DOS##LIBOBJS = $(OBJS)
+
+all-unix: all-libobjs
+
+includes: depend
+
+depend: $(SRCS)
+t_shs: t_shs.o shs.o $(SUPPORT_DEPLIB)
+ $(CC_LINK) -o t_shs t_shs.o shs.o $(SUPPORT_LIB)
+
+$(OUTPRE)t_shs.exe: $(OUTPRE)t_shs.obj $(OUTPRE)shs.obj
+ link -out:$@ $**
+
+t_shs3: t_shs3.o shs.o $(SUPPORT_DEPLIB)
+ $(CC_LINK) -o t_shs3 t_shs3.o shs.o $(SUPPORT_LIB)
+
+check-unix: t_shs t_shs3
+ $(RUN_TEST) $(C)t_shs -x
+ $(RUN_TEST) $(C)t_shs3
+
+check-windows: $(OUTPRE)t_shs.exe $(OUTPRE)t_shs3.exe
+ $(OUTPRE)$(C)t_shs.exe -x
+ $(OUTPRE)$(C)t_shs3.exe
+
+clean:
+ $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT) t_shs3$(EXEEXT) t_shs3.$(OBJEXT)
+
+clean-unix:: clean-libobjs
+
+@libobj_frag@
+
diff --git a/src/lib/crypto/builtin/sha1/deps b/src/lib/crypto/builtin/sha1/deps
new file mode 100644
index 000000000000..354116cdd43c
--- /dev/null
+++ b/src/lib/crypto/builtin/sha1/deps
@@ -0,0 +1,13 @@
+#
+# Generated makefile dependencies follow.
+#
+shs.so shs.po $(OUTPRE)shs.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h shs.c shs.h
diff --git a/src/lib/crypto/builtin/sha1/shs.c b/src/lib/crypto/builtin/sha1/shs.c
new file mode 100644
index 000000000000..f28a4fcbaf88
--- /dev/null
+++ b/src/lib/crypto/builtin/sha1/shs.c
@@ -0,0 +1,382 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#include "shs.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <string.h>
+
+/* The SHS f()-functions. The f1 and f3 functions can be optimized to
+ save one boolean operation each - thanks to Rich Schroeppel,
+ rcs@cs.arizona.edu for discovering this */
+
+#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
+#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
+#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
+#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
+
+/* The SHS Mysterious Constants */
+
+#define K1 0x5A827999L /* Rounds 0-19 */
+#define K2 0x6ED9EBA1L /* Rounds 20-39 */
+#define K3 0x8F1BBCDCL /* Rounds 40-59 */
+#define K4 0xCA62C1D6L /* Rounds 60-79 */
+
+/* SHS initial values */
+
+#define h0init 0x67452301L
+#define h1init 0xEFCDAB89L
+#define h2init 0x98BADCFEL
+#define h3init 0x10325476L
+#define h4init 0xC3D2E1F0L
+
+/* Note that it may be necessary to add parentheses to these macros if they
+ are to be called with expressions as arguments */
+
+/* 32-bit rotate left - kludged with shifts */
+
+#define ROTL(n,X) ((((X) << (n)) & 0xffffffff) | ((X) >> (32 - n)))
+
+/* The initial expanding function. The hash function is defined over an
+ 80-word expanded input array W, where the first 16 are copies of the input
+ data, and the remaining 64 are defined by
+
+ W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
+
+ This implementation generates these values on the fly in a circular
+ buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
+ optimization.
+
+ The updated SHS changes the expanding function by adding a rotate of 1
+ bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
+ for this information */
+
+#ifdef NEW_SHS
+#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
+ W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] )))
+#else
+#define expand(W,i) ( W[ i & 15 ] ^= W[ (i - 14) & 15 ] ^ \
+ W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] )
+#endif /* NEW_SHS */
+
+/* The prototype SHS sub-round. The fundamental sub-round is:
+
+ a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
+ b' = a;
+ c' = ROTL( 30, b );
+ d' = c;
+ e' = d;
+
+ but this is implemented by unrolling the loop 5 times and renaming the
+ variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
+ This code is then replicated 20 times for each of the 4 functions, using
+ the next 20 values from the W[] array each time */
+
+#define subRound(a, b, c, d, e, f, k, data) \
+ ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, \
+ e &= 0xffffffff, b = ROTL( 30, b ) )
+
+/* Initialize the SHS values */
+
+void shsInit(SHS_INFO *shsInfo)
+{
+ /* Set the h-vars to their initial values */
+ shsInfo->digest[ 0 ] = h0init;
+ shsInfo->digest[ 1 ] = h1init;
+ shsInfo->digest[ 2 ] = h2init;
+ shsInfo->digest[ 3 ] = h3init;
+ shsInfo->digest[ 4 ] = h4init;
+
+ /* Initialise bit count */
+ shsInfo->countLo = shsInfo->countHi = 0;
+}
+
+/* Perform the SHS transformation. Note that this code, like MD5, seems to
+ break some optimizing compilers due to the complexity of the expressions
+ and the size of the basic block. It may be necessary to split it into
+ sections, e.g. based on the four subrounds
+
+ Note that this corrupts the shsInfo->data area */
+
+static void SHSTransform (SHS_LONG *digest, const SHS_LONG *data);
+
+static
+void SHSTransform(SHS_LONG *digest, const SHS_LONG *data)
+{
+ SHS_LONG A, B, C, D, E; /* Local vars */
+ SHS_LONG eData[ 16 ]; /* Expanded data */
+
+ /* Set up first buffer and local data buffer */
+ A = digest[ 0 ];
+ B = digest[ 1 ];
+ C = digest[ 2 ];
+ D = digest[ 3 ];
+ E = digest[ 4 ];
+ memcpy(eData, data, sizeof (eData));
+
+#if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
+
+ {
+ int i;
+ SHS_LONG temp;
+ for (i = 0; i < 20; i++) {
+ SHS_LONG x = (i < 16) ? eData[i] : expand(eData, i);
+ subRound(A, B, C, D, E, f1, K1, x);
+ temp = E, E = D, D = C, C = B, B = A, A = temp;
+ }
+ for (i = 20; i < 40; i++) {
+ subRound(A, B, C, D, E, f2, K2, expand(eData, i));
+ temp = E, E = D, D = C, C = B, B = A, A = temp;
+ }
+ for (i = 40; i < 60; i++) {
+ subRound(A, B, C, D, E, f3, K3, expand(eData, i));
+ temp = E, E = D, D = C, C = B, B = A, A = temp;
+ }
+ for (i = 60; i < 80; i++) {
+ subRound(A, B, C, D, E, f4, K4, expand(eData, i));
+ temp = E, E = D, D = C, C = B, B = A, A = temp;
+ }
+ }
+
+#else
+
+ /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
+ subRound( A, B, C, D, E, f1, K1, eData[ 0 ] );
+ subRound( E, A, B, C, D, f1, K1, eData[ 1 ] );
+ subRound( D, E, A, B, C, f1, K1, eData[ 2 ] );
+ subRound( C, D, E, A, B, f1, K1, eData[ 3 ] );
+ subRound( B, C, D, E, A, f1, K1, eData[ 4 ] );
+ subRound( A, B, C, D, E, f1, K1, eData[ 5 ] );
+ subRound( E, A, B, C, D, f1, K1, eData[ 6 ] );
+ subRound( D, E, A, B, C, f1, K1, eData[ 7 ] );
+ subRound( C, D, E, A, B, f1, K1, eData[ 8 ] );
+ subRound( B, C, D, E, A, f1, K1, eData[ 9 ] );
+ subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
+ subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
+ subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
+ subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
+ subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
+ subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
+ subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
+ subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
+ subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
+ subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
+
+ subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
+ subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
+ subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
+ subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
+ subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
+ subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
+ subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
+ subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
+ subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
+ subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
+ subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
+ subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
+ subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
+ subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
+ subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
+ subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
+ subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
+ subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
+ subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
+ subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
+
+ subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
+ subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
+ subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
+ subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
+ subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
+ subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
+ subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
+ subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
+ subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
+ subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
+ subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
+ subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
+ subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
+ subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
+ subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
+ subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
+ subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
+ subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
+ subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
+ subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
+
+ subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
+ subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
+ subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
+ subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
+ subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
+ subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
+ subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
+ subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
+ subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
+ subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
+ subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
+ subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
+ subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
+ subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
+ subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
+ subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
+ subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
+ subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
+ subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
+ subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
+
+#endif
+
+ /* Build message digest */
+ digest[ 0 ] += A;
+ digest[ 0 ] &= 0xffffffff;
+ digest[ 1 ] += B;
+ digest[ 1 ] &= 0xffffffff;
+ digest[ 2 ] += C;
+ digest[ 2 ] &= 0xffffffff;
+ digest[ 3 ] += D;
+ digest[ 3 ] &= 0xffffffff;
+ digest[ 4 ] += E;
+ digest[ 4 ] &= 0xffffffff;
+}
+
+/* Update SHS for a block of data */
+
+void shsUpdate(SHS_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count)
+{
+ SHS_LONG tmp;
+ unsigned int dataCount;
+ int canfill;
+ SHS_LONG *lp;
+
+ /* Update bitcount */
+ tmp = shsInfo->countLo;
+ shsInfo->countLo = tmp + (((SHS_LONG) count) << 3 );
+ if ((shsInfo->countLo &= 0xffffffff) < tmp)
+ shsInfo->countHi++; /* Carry from low to high */
+ shsInfo->countHi += count >> 29;
+
+ /* Get count of bytes already in data */
+ dataCount = (tmp >> 3) & 0x3F;
+
+ /* Handle any leading odd-sized chunks */
+ if (dataCount) {
+ lp = shsInfo->data + dataCount / 4;
+ dataCount = SHS_DATASIZE - dataCount;
+ canfill = (count >= dataCount);
+
+ if (dataCount % 4) {
+ /* Fill out a full 32 bit word first if needed -- this
+ is not very efficient (computed shift amount),
+ but it shouldn't happen often. */
+ while (dataCount % 4 && count > 0) {
+ *lp |= (SHS_LONG) *buffer++ << ((--dataCount % 4) * 8);
+ count--;
+ }
+ lp++;
+ }
+ while (lp < shsInfo->data + 16) {
+ if (count < 4) {
+ *lp = 0;
+ switch (count % 4) {
+ case 3:
+ *lp |= (SHS_LONG) buffer[2] << 8;
+ case 2:
+ *lp |= (SHS_LONG) buffer[1] << 16;
+ case 1:
+ *lp |= (SHS_LONG) buffer[0] << 24;
+ }
+ count = 0;
+ break; /* out of while loop */
+ }
+ *lp++ = load_32_be(buffer);
+ buffer += 4;
+ count -= 4;
+ }
+ if (canfill) {
+ SHSTransform(shsInfo->digest, shsInfo->data);
+ }
+ }
+
+ /* Process data in SHS_DATASIZE chunks */
+ while (count >= SHS_DATASIZE) {
+ lp = shsInfo->data;
+ while (lp < shsInfo->data + 16) {
+ *lp++ = load_32_be(buffer);
+ buffer += 4;
+ }
+ SHSTransform(shsInfo->digest, shsInfo->data);
+ count -= SHS_DATASIZE;
+ }
+
+ if (count > 0) {
+ lp = shsInfo->data;
+ while (count > 4) {
+ *lp++ = load_32_be(buffer);
+ buffer += 4;
+ count -= 4;
+ }
+ *lp = 0;
+ switch (count % 4) {
+ case 0:
+ *lp |= ((SHS_LONG) buffer[3]);
+ case 3:
+ *lp |= ((SHS_LONG) buffer[2]) << 8;
+ case 2:
+ *lp |= ((SHS_LONG) buffer[1]) << 16;
+ case 1:
+ *lp |= ((SHS_LONG) buffer[0]) << 24;
+ }
+ }
+}
+
+/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
+ 1 0* (64-bit count of bits processed, MSB-first) */
+
+void shsFinal(SHS_INFO *shsInfo)
+{
+ int count;
+ SHS_LONG *lp;
+
+ /* Compute number of bytes mod 64 */
+ count = (int) shsInfo->countLo;
+ count = (count >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ lp = shsInfo->data + count / 4;
+ switch (count % 4) {
+ case 3:
+ *lp++ |= (SHS_LONG) 0x80;
+ break;
+ case 2:
+ *lp++ |= (SHS_LONG) 0x80 << 8;
+ break;
+ case 1:
+ *lp++ |= (SHS_LONG) 0x80 << 16;
+ break;
+ case 0:
+ *lp++ = (SHS_LONG) 0x80 << 24;
+ }
+
+ /* at this point, lp can point *past* shsInfo->data. If it points
+ there, just Transform and reset. If it points to the last
+ element, set that to zero. This pads out to 64 bytes if not
+ enough room for length words */
+
+ if (lp == shsInfo->data + 15)
+ *lp++ = 0;
+
+ if (lp == shsInfo->data + 16) {
+ SHSTransform(shsInfo->digest, shsInfo->data);
+ lp = shsInfo->data;
+ }
+
+ /* Pad out to 56 bytes */
+ while (lp < shsInfo->data + 14)
+ *lp++ = 0;
+
+ /* Append length in bits and transform */
+ *lp++ = shsInfo->countHi;
+ *lp++ = shsInfo->countLo;
+ SHSTransform(shsInfo->digest, shsInfo->data);
+}
diff --git a/src/lib/crypto/builtin/sha1/shs.h b/src/lib/crypto/builtin/sha1/shs.h
new file mode 100644
index 000000000000..e1872f2e5105
--- /dev/null
+++ b/src/lib/crypto/builtin/sha1/shs.h
@@ -0,0 +1,46 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#ifndef _SHS_DEFINED
+
+#include "k5-int.h"
+
+#define _SHS_DEFINED
+
+/* Some useful types */
+
+typedef krb5_octet SHS_BYTE;
+typedef krb5_ui_4 SHS_LONG;
+
+/* Define the following to use the updated SHS implementation */
+#define NEW_SHS /**/
+
+/* The SHS block size and message digest sizes, in bytes */
+
+#define SHS_DATASIZE 64
+#define SHS_DIGESTSIZE 20
+
+/* The structure for storing SHS info */
+
+typedef struct {
+ SHS_LONG digest[ 5 ]; /* Message digest */
+ SHS_LONG countLo, countHi; /* 64-bit bit count */
+ SHS_LONG data[ 16 ]; /* SHS data buffer */
+} SHS_INFO;
+
+/* Message digest functions (shs.c) */
+void shsInit(SHS_INFO *shsInfo);
+void shsUpdate(SHS_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count);
+void shsFinal(SHS_INFO *shsInfo);
+
+
+/* Keyed Message digest functions (hmac_sha.c) */
+krb5_error_code hmac_sha(krb5_octet *text,
+ int text_len,
+ krb5_octet *key,
+ int key_len,
+ krb5_octet *digest);
+
+
+#define NIST_SHA_CKSUM_LENGTH SHS_DIGESTSIZE
+#define HMAC_SHA_CKSUM_LENGTH SHS_DIGESTSIZE
+
+#endif /* _SHS_DEFINED */
diff --git a/src/lib/crypto/builtin/sha1/t_shs.c b/src/lib/crypto/builtin/sha1/t_shs.c
new file mode 100644
index 000000000000..08157b662230
--- /dev/null
+++ b/src/lib/crypto/builtin/sha1/t_shs.c
@@ -0,0 +1,136 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/****************************************************************************
+ * *
+ * SHS Test Code *
+ * *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "shs.h"
+
+/* Test the SHS implementation */
+
+#ifdef NEW_SHS
+
+static SHS_LONG shsTestResults[][ 5 ] = {
+ { 0xA9993E36L, 0x4706816AL, 0xBA3E2571L, 0x7850C26CL, 0x9CD0D89DL, },
+ { 0x84983E44L, 0x1C3BD26EL, 0xBAAE4AA1L, 0xF95129E5L, 0xE54670F1L, },
+ { 0x34AA973CL, 0xD4C4DAA4L, 0xF61EEB2BL, 0xDBAD2731L, 0x6534016FL, }
+};
+
+#else
+
+static SHS_LONG shsTestResults[][ 5 ] = {
+ { 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L },
+ { 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L },
+ { 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L }
+};
+#endif /* NEW_SHS */
+
+static int compareSHSresults(shsInfo, shsTestLevel)
+ SHS_INFO *shsInfo;
+ int shsTestLevel;
+{
+ int i, fail = 0;
+
+ /* Compare the returned digest and required values */
+ for( i = 0; i < 5; i++ )
+ if( shsInfo->digest[ i ] != shsTestResults[ shsTestLevel ][ i ] )
+ fail = 1;
+ if (fail) {
+ printf("\nExpected: ");
+ for (i = 0; i < 5; i++) {
+ printf("%8.8lx ", (unsigned long) shsTestResults[shsTestLevel][i]);
+ }
+ printf("\nGot: ");
+ for (i = 0; i < 5; i++) {
+ printf("%8.8lx ", (unsigned long) shsInfo->digest[i]);
+ }
+ printf("\n");
+ return( -1 );
+ }
+ return( 0 );
+}
+
+int
+main()
+{
+ SHS_INFO shsInfo;
+ unsigned int i;
+#if 0
+ time_t secondCount;
+ SHS_BYTE data[ 200 ];
+#endif
+
+ /* Make sure we've got the endianness set right. If the machine is
+ big-endian (up to 64 bits) the following value will be signed,
+ otherwise it will be unsigned. Unfortunately we can't test for odd
+ things like middle-endianness without knowing the size of the data
+ types */
+
+ /* Test SHS against values given in SHS standards document */
+ printf( "Running SHS test 1 ... " );
+ shsInit( &shsInfo );
+ shsUpdate( &shsInfo, ( SHS_BYTE * ) "abc", 3 );
+ shsFinal( &shsInfo );
+ if( compareSHSresults( &shsInfo, 0 ) == -1 )
+ {
+ putchar( '\n' );
+ puts( "SHS test 1 failed" );
+ exit( -1 );
+ }
+#ifdef NEW_SHS
+ puts( "passed, result= A9993E364706816ABA3E25717850C26C9CD0D89D" );
+#else
+ puts( "passed, result= 0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880" );
+#endif /* NEW_SHS */
+
+ printf( "Running SHS test 2 ... " );
+ shsInit( &shsInfo );
+ shsUpdate( &shsInfo, ( SHS_BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 );
+ shsFinal( &shsInfo );
+ if( compareSHSresults( &shsInfo, 1 ) == -1 )
+ {
+ putchar( '\n' );
+ puts( "SHS test 2 failed" );
+ exit( -1 );
+ }
+#ifdef NEW_SHS
+ puts( "passed, result= 84983E441C3BD26EBAAE4AA1F95129E5E54670F1" );
+#else
+ puts( "passed, result= D2516EE1ACFA5BAF33DFC1C471E438449EF134C8" );
+#endif /* NEW_SHS */
+
+ printf( "Running SHS test 3 ... " );
+ shsInit( &shsInfo );
+ for( i = 0; i < 15625; i++ )
+ shsUpdate( &shsInfo, ( SHS_BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 );
+ shsFinal( &shsInfo );
+ if( compareSHSresults( &shsInfo, 2 ) == -1 )
+ {
+ putchar( '\n' );
+ puts( "SHS test 3 failed" );
+ exit( -1 );
+ }
+#ifdef NEW_SHS
+ puts( "passed, result= 34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" );
+#else
+ puts( "passed, result= 3232AFFA48628A26653B5AAA44541FD90D690603" );
+#endif /* NEW_SHS */
+
+#if 0
+ printf( "\nTesting speed for 100MB data... " );
+ shsInit( &shsInfo );
+ secondCount = time( NULL );
+ for( i = 0; i < 500000U; i++ )
+ shsUpdate( &shsInfo, data, 200 );
+ secondCount = time( NULL ) - secondCount;
+ printf( "done. Time = %ld seconds, %ld kbytes/second.\n", \
+ secondCount, 100500L / secondCount );
+#endif
+
+ puts( "\nAll SHS tests passed" );
+ exit( 0 );
+}
diff --git a/src/lib/crypto/builtin/sha1/t_shs3.c b/src/lib/crypto/builtin/sha1/t_shs3.c
new file mode 100644
index 000000000000..f7932ef0fd44
--- /dev/null
+++ b/src/lib/crypto/builtin/sha1/t_shs3.c
@@ -0,0 +1,594 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* test shs code */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "shs.h"
+
+static void process(void);
+static void test1(void);
+static void test2(void);
+static void test3(void);
+static void test4(void);
+static void test5(void);
+static void test6(void);
+static void test7(void);
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+ array of longwords. It is possible to make the code endianness-
+ independant by fiddling around with data at the byte level, but this
+ makes for very slow code, so we rely on the user to sort out endianness
+ at compile time */
+
+static void longReverse( SHS_LONG *buffer, int byteCount )
+{
+ SHS_LONG value;
+ static int init = 0;
+ char *cp;
+
+ switch (init) {
+ case 0:
+ init=1;
+ cp = (char *) &init;
+ if (*cp == 1) {
+ init=2;
+ break;
+ }
+ init=1;
+ /* fall through - MSB */
+ case 1:
+ return;
+ }
+
+ byteCount /= sizeof( SHS_LONG );
+ while( byteCount-- ) {
+ value = *buffer;
+ value = ( ( value & 0xFF00FF00L ) >> 8 ) |
+ ( ( value & 0x00FF00FFL ) << 8 );
+ *buffer++ = ( value << 16 ) | ( value >> 16 );
+ }
+}
+
+int rc;
+int mode;
+int Dflag;
+
+int
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ char *argp;
+
+ while (--argc > 0) if (*(argp = *++argv)=='-')
+ while (*++argp) switch(*argp)
+ {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ if (mode) goto Usage;
+ mode = *argp;
+ break;
+ case 'D':
+ if (argc <= 1) goto Usage;
+ --argc;
+ Dflag = atoi(*++argv);
+ break;
+ case '-':
+ break;
+ default:
+ fprintf (stderr,"Bad switch char <%c>\n", *argp);
+ Usage:
+ fprintf(stderr, "Usage: t_shs [-1234567] [-D #]\n");
+ exit(1);
+ }
+ else goto Usage;
+
+ process();
+ exit(rc);
+}
+
+static void process(void)
+{
+ switch(mode)
+ {
+ case '1':
+ test1();
+ break;
+ case '2':
+ test2();
+ break;
+ case '3':
+ test3();
+ break;
+ case '4':
+ test4();
+ break;
+ case '5':
+ test5();
+ break;
+ case '6':
+ test6();
+ break;
+ case '7':
+ test7();
+ break;
+ default:
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
+ }
+}
+
+#ifndef shsDigest
+static unsigned char *
+shsDigest(si)
+ SHS_INFO *si;
+{
+ longReverse(si->digest, SHS_DIGESTSIZE);
+ return (unsigned char*) si->digest;
+}
+#endif
+
+unsigned char results1[SHS_DIGESTSIZE] = {
+ 0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,
+ 0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d};
+
+static void test1(void)
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i;
+
+ printf("Running SHS test 1 ...\n");
+ shsInit(si);
+ shsUpdate(si, (SHS_BYTE *) "abc", 3);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if ((failed = memcmp(digest, results1, SHS_DIGESTSIZE)) != 0)
+ {
+ fprintf(stderr,"SHS test 1 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results1[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results2[SHS_DIGESTSIZE] = {
+ 0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,
+ 0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1};
+
+static void test2(void)
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i;
+
+ printf("Running SHS test 2 ...\n");
+ shsInit(si);
+ shsUpdate(si,
+ (SHS_BYTE *) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ 56);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if ((failed = memcmp(digest, results2, SHS_DIGESTSIZE)) != 0)
+ {
+ fprintf(stderr,"SHS test 2 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results2[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results3[SHS_DIGESTSIZE] = {
+ 0x34,0xaa,0x97,0x3c,0xd4,0xc4,0xda,0xa4,0xf6,0x1e,
+ 0xeb,0x2b,0xdb,0xad,0x27,0x31,0x65,0x34,0x01,0x6f};
+
+static void test3(void)
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i;
+
+ printf("Running SHS test 3 ...\n");
+ shsInit(si);
+ for (i = 0; i < 15625; ++i)
+ shsUpdate(si,
+ (SHS_BYTE *) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ 64);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if ((failed = memcmp(digest, results3, SHS_DIGESTSIZE)) != 0)
+ {
+ fprintf(stderr,"SHS test 3 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results3[i]);
+ }
+ printf("\n");
+}
+
+unsigned char randdata[] = {
+ 0xfe,0x28,0x79,0x25,0xf5,0x03,0xf9,0x1c,0xcd,0x70,0x7b,0xb0,0x42,0x02,0xb8,0x2f,
+ 0xf3,0x63,0xa2,0x79,0x8e,0x9b,0x33,0xd7,0x2b,0xc4,0xb4,0xd2,0xcb,0x61,0xec,0xbb,
+ 0x94,0xe1,0x8f,0x53,0x80,0x55,0xd9,0x90,0xb2,0x03,0x58,0xfa,0xa6,0xe5,0x18,0x57,
+ 0x68,0x04,0x24,0x98,0x41,0x7e,0x84,0xeb,0xc1,0x39,0xbc,0x1d,0xf7,0x4e,0x92,0x72,
+ 0x1a,0x5b,0xb6,0x99,0x43,0xa5,0x0a,0x45,0x73,0x55,0xfd,0x57,0x83,0x45,0x36,0x5c,
+ 0xfd,0x39,0x08,0x6e,0xe2,0x01,0x9a,0x8c,0x4e,0x39,0xd2,0x0d,0x5f,0x0e,0x35,0x15,
+ 0xb9,0xac,0x5f,0xa1,0x8a,0xe6,0xdd,0x6e,0x68,0x9d,0xf6,0x29,0x95,0xf6,0x7d,0x7b,
+ 0xd9,0x5e,0xf4,0x67,0x25,0xbd,0xee,0xed,0x53,0x60,0xb0,0x47,0xdf,0xef,0xf4,0x41,
+ 0xbd,0x45,0xcf,0x5c,0x93,0x41,0x87,0x97,0x82,0x39,0x20,0x66,0xb4,0xda,0xcb,0x66,
+ 0x93,0x02,0x2e,0x7f,0x94,0x4c,0xc7,0x3b,0x2c,0xcf,0xf6,0x99,0x6f,0x13,0xf1,0xc5,
+ 0x28,0x2b,0xa6,0x6c,0x39,0x26,0x7f,0x76,0x24,0x4a,0x6e,0x01,0x40,0x63,0xf8,0x00,
+ 0x06,0x23,0x5a,0xaa,0xa6,0x2f,0xd1,0x37,0xc7,0xcc,0x76,0xe9,0x54,0x1e,0x57,0x73,
+ 0xf5,0x33,0xaa,0x96,0xbe,0x35,0xcd,0x1d,0xd5,0x7d,0xac,0x50,0xd5,0xf8,0x47,0x2d,
+ 0xd6,0x93,0x5f,0x6e,0x38,0xd3,0xac,0xd0,0x7e,0xad,0x9e,0xf8,0x87,0x95,0x63,0x15,
+ 0x65,0xa3,0xd4,0xb3,0x9a,0x6c,0xac,0xcd,0x2a,0x54,0x83,0x13,0xc4,0xb4,0x94,0xfa,
+ 0x76,0x87,0xc5,0x8b,0x4a,0x10,0x92,0x05,0xd1,0x0e,0x97,0xfd,0xc8,0xfb,0xc5,0xdc,
+ 0x21,0x4c,0xc8,0x77,0x5c,0xed,0x32,0x22,0x77,0xc1,0x38,0x30,0xd7,0x8e,0x2a,0x70,
+ 0x72,0x67,0x13,0xe4,0xb7,0x18,0xd4,0x76,0xdd,0x32,0x12,0xf4,0x5d,0xc9,0xec,0xc1,
+ 0x2c,0x8a,0xfe,0x08,0x6c,0xea,0xf6,0xab,0x5a,0x0e,0x8e,0x81,0x1d,0xc8,0x5a,0x4b,
+ 0xed,0xb9,0x7f,0x4b,0x67,0xe3,0x65,0x46,0xc9,0xf2,0xab,0x37,0x0a,0x98,0x67,0x5b,
+ 0xb1,0x3b,0x02,0x91,0x38,0x71,0xea,0x62,0x88,0xae,0xb6,0xdb,0xfc,0x55,0x79,0x33,
+ 0x69,0x95,0x51,0xb6,0xe1,0x3b,0xab,0x22,0x68,0x54,0xf9,0x89,0x9c,0x94,0xe0,0xe3,
+ 0xd3,0x48,0x5c,0xe9,0x78,0x5b,0xb3,0x4b,0xba,0xd8,0x48,0xd8,0xaf,0x91,0x4e,0x23,
+ 0x38,0x23,0x23,0x6c,0xdf,0x2e,0xf0,0xff,0xac,0x1d,0x2d,0x27,0x10,0x45,0xa3,0x2d,
+ 0x8b,0x00,0xcd,0xe2,0xfc,0xb7,0xdb,0x52,0x13,0xb7,0x66,0x79,0xd9,0xd8,0x29,0x0e,
+ 0x32,0xbd,0x52,0x6b,0x75,0x71,0x08,0x83,0x1b,0x67,0x28,0x93,0x97,0x97,0x32,0xff,
+ 0x8b,0xd3,0x98,0xa3,0xce,0x2b,0x88,0x37,0x1c,0xcc,0xa0,0xd1,0x19,0x9b,0xe6,0x11,
+ 0xfc,0xc0,0x3c,0x4e,0xe1,0x35,0x49,0x29,0x19,0xcf,0x1d,0xe1,0x60,0x74,0xc0,0xe9,
+ 0xf7,0xb4,0x99,0xa0,0x23,0x50,0x51,0x78,0xcf,0xc0,0xe5,0xc2,0x1c,0x16,0xd2,0x24,
+ 0x5a,0x63,0x54,0x83,0xaa,0x74,0x3d,0x41,0x0d,0x52,0xee,0xfe,0x0f,0x4d,0x13,0xe1,
+ 0x27,0x00,0xc4,0xf3,0x2b,0x55,0xe0,0x9c,0x81,0xe0,0xfc,0xc2,0x13,0xd4,0x39,0x09
+};
+
+unsigned char results4[SHS_DIGESTSIZE] = {
+ 0x13,0x62,0xfc,0x87,0x68,0x33,0xd5,0x1d,0x2f,0x0c,
+ 0x73,0xe3,0xfb,0x87,0x6a,0x6b,0xc3,0x25,0x54,0xfc};
+
+static void test4(void)
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i;
+
+ printf("Running SHS test 4 ...\n");
+ shsInit(si);
+ shsUpdate(si, randdata, 19);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if ((failed = memcmp(digest, results4, SHS_DIGESTSIZE)) != 0)
+ {
+ fprintf(stderr,"SHS test 4 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results4[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results5[SHS_DIGESTSIZE] = {
+ 0x19,0x4d,0xf6,0xeb,0x8e,0x02,0x6d,0x37,0x58,0x64,
+ 0xe5,0x95,0x19,0x2a,0xdd,0x1c,0xc4,0x3c,0x24,0x86};
+
+static void test5(void)
+{
+ SHS_INFO si[1];
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ int i;
+
+ printf("Running SHS test 5 ...\n");
+ shsInit(si);
+ shsUpdate(si, randdata, 19);
+ shsUpdate(si, randdata+32, 15);
+ shsFinal(si);
+ memcpy(digest, shsDigest(si), SHS_DIGESTSIZE);
+ if ((failed = memcmp(digest, results5, SHS_DIGESTSIZE)) != 0)
+ {
+ fprintf(stderr,"SHS test 5 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results5[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results6[SHS_DIGESTSIZE] = {
+ 0x4e,0x16,0x57,0x9d,0x4b,0x48,0xa9,0x1c,0x88,0x72,
+ 0x83,0xdb,0x88,0xd1,0xea,0x3a,0x45,0xdf,0xa1,0x10};
+
+static void test6(void)
+{
+ struct {
+ unsigned long pad1;
+ SHS_INFO si1;
+ unsigned long pad2;
+ SHS_INFO si2;
+ unsigned long pad3;
+ } sdata;
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ unsigned int i, j;
+
+ printf("Running SHS test 6 ...\n");
+ sdata.pad1 = 0x12345678;
+ sdata.pad2 = 0x87654321;
+ sdata.pad3 = 0x78563412;
+ shsInit((&sdata.si2));
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #20 %#lx\n",
+ sdata.pad2);
+ sdata.pad2 = 0x87654321;
+ }
+ if (sdata.pad3 != 0x78563412) {
+ printf ("Overrun #21 %#lx\n",
+ sdata.pad3);
+ sdata.pad3 = 0x78563412;
+ }
+ for (i = 0; i < 400; ++i)
+ {
+ shsInit(&sdata.si1);
+ if (sdata.pad1 != 0x12345678) {
+ printf ("Overrun #22 %#lx at %d\n",
+ sdata.pad1, i);
+ sdata.pad1 = 0x12345678;
+ }
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #23 %#lx at %d\n",
+ sdata.pad2, i);
+ sdata.pad2 = 0x87654321;
+ }
+ shsUpdate(&sdata.si1, (randdata+sizeof(randdata))-i, i);
+ if (sdata.pad1 != 0x12345678) {
+ printf ("Overrun #24 %#lx at %d\n",
+ sdata.pad1, i);
+ sdata.pad1 = 0x12345678;
+ }
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #25 %#lx at %d\n",
+ sdata.pad2, i);
+ sdata.pad2 = 0x87654321;
+ }
+ shsFinal(&sdata.si1);
+ if (sdata.pad1 != 0x12345678) {
+ printf ("Overrun #26 %#lx at %d\n",
+ sdata.pad1, i);
+ sdata.pad1 = 0x12345678;
+ }
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #27 %#lx at %d\n",
+ sdata.pad2, i);
+ sdata.pad2 = 0x87654321;
+ }
+ memcpy(digest, shsDigest(&sdata.si1), SHS_DIGESTSIZE);
+ if (Dflag & 1)
+ {
+ printf ("%d: ", i);
+ for (j = 0; j < SHS_DIGESTSIZE; ++j)
+ printf("%02x",digest[j]);
+ printf("\n");
+ }
+ shsUpdate((&sdata.si2), digest, SHS_DIGESTSIZE);
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #28 %#lx at %d\n",
+ sdata.pad2, i);
+ sdata.pad2 = 0x87654321;
+ }
+ if (sdata.pad3 != 0x78563412) {
+ printf ("Overrun #29 %#lx at %d\n",
+ sdata.pad3, i);
+ sdata.pad3 = 0x78563412;
+ }
+ if (Dflag & 2)
+ printf ("%d: %08lx%08lx%08lx%08lx%08lx\n",
+ i,
+ (unsigned long) sdata.si2.digest[0],
+ (unsigned long) sdata.si2.digest[1],
+ (unsigned long) sdata.si2.digest[2],
+ (unsigned long) sdata.si2.digest[3],
+ (unsigned long) sdata.si2.digest[4]);
+ }
+ shsFinal((&sdata.si2));
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #30 %#lx\n",
+ sdata.pad2);
+ sdata.pad2 = 0x87654321;
+ }
+ if (sdata.pad3 != 0x78563412) {
+ printf ("Overrun #31 %#lx\n",
+ sdata.pad3);
+ sdata.pad3 = 0x78563412;
+ }
+ memcpy(digest, shsDigest((&sdata.si2)), SHS_DIGESTSIZE);
+ if ((failed = memcmp(digest, results6, SHS_DIGESTSIZE)) != 0)
+ {
+ fprintf(stderr,"SHS test 6 failed!\n");
+ rc = 1;
+ }
+ printf ("%s, results = ", failed ? "Failed" : "Passed");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",digest[i]);
+ if (failed)
+ {
+ printf ("\n, expected ");
+ for (i = 0; i < SHS_DIGESTSIZE; ++i)
+ printf("%02x",results6[i]);
+ }
+ printf("\n");
+}
+
+unsigned char results7[SHS_DIGESTSIZE] = {
+ 0x89,0x41,0x65,0xce,0x76,0xc1,0xd1,0xd1,0xc3,0x6f,
+ 0xab,0x92,0x79,0x30,0x01,0x71,0x63,0x1f,0x74,0xfe};
+
+unsigned int jfsize[] = {0,1,31,32,
+ 33,55,56,63,
+ 64,65,71,72,
+ 73,95,96,97,
+ 119,120,123,127};
+unsigned int kfsize[] = {0,1,31,32,33,55,56,63};
+
+static void test7(void)
+{
+ struct {
+ unsigned long pad1;
+ SHS_INFO si1;
+ unsigned long pad2;
+ SHS_INFO si2;
+ unsigned long pad3;
+ } sdata;
+ unsigned char digest[SHS_DIGESTSIZE];
+ int failed;
+ unsigned int i, j, k, l;
+
+ printf("Running SHS test 7 ...\n");
+ sdata.pad1 = 0x12345678;
+ sdata.pad2 = 0x87654321;
+ sdata.pad3 = 0x78563412;
+ shsInit((&sdata.si2));
+ for (i = 1; i <= 128; ++i)
+ for (j = 0; j < 20; ++j)
+ for (k = 0; k < 8; ++k)
+ {
+ shsInit(&sdata.si1);
+ shsUpdate(&sdata.si1, (randdata+80+j), i);
+ if (sdata.pad1 != 0x12345678) {
+ printf ("Overrun #1 %#lx at %d,%d,%d\n",
+ sdata.pad1, i,j,k);
+ sdata.pad1 = 0x12345678;
+ }
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #2 %#lx at %d,%d,%d\n",
+ sdata.pad2, i,j,k);
+ sdata.pad2 = 0x87654321;
+ }
+ shsUpdate(&sdata.si1, randdata+i, jfsize[j]);
+ if (sdata.pad1 != 0x12345678) {
+ printf ("Overrun #3 %#lx at %d,%d,%d\n",
+ sdata.pad1, i,j,k);
+ sdata.pad1 = 0x12345678;
+ }
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #4 %#lx at %d,%d,%d\n",
+ sdata.pad2, i,j,k);
+ sdata.pad2 = 0x87654321;
+ }
+ if (k) shsUpdate(&sdata.si1, randdata+(i^j), kfsize[k]);
+ if (sdata.pad1 != 0x12345678) {
+ printf ("Overrun #5 %#lx at %d,%d,%d\n",
+ sdata.pad1, i,j,k);
+ sdata.pad1 = 0x12345678;
+ }
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #6 %#lx at %d,%d,%d\n",
+ sdata.pad2, i,j,k);
+ sdata.pad2 = 0x87654321;
+ }
+ shsFinal(&sdata.si1);
+ if (sdata.pad1 != 0x12345678) {
+ printf ("Overrun #7 %#lx at %d,%d,%d\n",
+ sdata.pad1, i,j,k);
+ sdata.pad1 = 0x12345678;
+ }
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #8 %#lx at %d,%d,%d\n",
+ sdata.pad2, i,j,k);
+ sdata.pad2 = 0x87654321;
+ }
+ memcpy(digest, shsDigest(&sdata.si1), SHS_DIGESTSIZE);
+ if (Dflag & 1)
+ {
+ printf ("%d,%d,%d: ", i, j, k);
+ for (l = 0; l < SHS_DIGESTSIZE; ++l)
+ printf("%02x",digest[l]);
+ printf("\n");
+ }
+ shsUpdate((&sdata.si2), digest, SHS_DIGESTSIZE);
+ if (sdata.pad2 != 0x87654321) {
+ printf ("Overrun #9 %#lx at %d,%d,%d\n",
+ sdata.pad2, i,j,k);
+ sdata.pad2 = 0x87654321;
+ }
+ if (sdata.pad3 != 0x78563412) {
+ printf ("Overrun #10 %#lx at %d,%d,%d\n",
+ sdata.pad3, i,j,k);
+ sdata.pad3 = 0x78563412;
+ }
+ if (Dflag & 2)
+ printf ("%d,%d,%d: %08lx%08lx%08lx%08lx%08lx\n",