svn rev #24679: trunk/src/ lib/crypto/ lib/crypto/crypto_tests/ lib/crypto/krb/
ghudson@MIT.EDU
ghudson at MIT.EDU
Sat Mar 5 08:31:02 EST 2011
http://src.mit.edu/fisheye/changelog/krb5/?cs=24679
Commit By: ghudson
Log Message:
Flatten lib/crypto/krb, as its seven subdirectories only contained a
few source file each (often only 1-2).
Changed Files:
U trunk/src/configure.in
U trunk/src/lib/crypto/Makefile.in
A trunk/src/lib/crypto/crypto_tests/CRC.pm
A trunk/src/lib/crypto/crypto_tests/Poly.pm
A trunk/src/lib/crypto/crypto_tests/crc.pl
U trunk/src/lib/crypto/krb/Makefile.in
D trunk/src/lib/crypto/krb/arcfour/
D trunk/src/lib/crypto/krb/checksum/
A trunk/src/lib/crypto/krb/checksum_cbc.c
A trunk/src/lib/crypto/krb/checksum_confounder.c
A trunk/src/lib/crypto/krb/checksum_dk_cmac.c
A trunk/src/lib/crypto/krb/checksum_dk_hmac.c
A trunk/src/lib/crypto/krb/checksum_hmac_md5.c
A trunk/src/lib/crypto/krb/checksum_unkeyed.c
A trunk/src/lib/crypto/krb/cmac.c
D trunk/src/lib/crypto/krb/crc32/
A trunk/src/lib/crypto/krb/crc32.c
U trunk/src/lib/crypto/krb/deps
A trunk/src/lib/crypto/krb/derive.c
D trunk/src/lib/crypto/krb/dk/
A trunk/src/lib/crypto/krb/enc_dk_cmac.c
A trunk/src/lib/crypto/krb/enc_dk_hmac.c
A trunk/src/lib/crypto/krb/enc_old.c
A trunk/src/lib/crypto/krb/enc_raw.c
A trunk/src/lib/crypto/krb/enc_rc4.c
D trunk/src/lib/crypto/krb/hash_provider/
D trunk/src/lib/crypto/krb/old/
D trunk/src/lib/crypto/krb/prf/
A trunk/src/lib/crypto/krb/prf_cmac.c
A trunk/src/lib/crypto/krb/prf_des.c
A trunk/src/lib/crypto/krb/prf_dk.c
A trunk/src/lib/crypto/krb/prf_rc4.c
D trunk/src/lib/crypto/krb/raw/
A trunk/src/lib/crypto/krb/s2k_des.c
A trunk/src/lib/crypto/krb/s2k_pbkdf2.c
A trunk/src/lib/crypto/krb/s2k_rc4.c
Modified: trunk/src/configure.in
===================================================================
--- trunk/src/configure.in 2011-03-03 15:21:11 UTC (rev 24678)
+++ trunk/src/configure.in 2011-03-05 13:31:02 UTC (rev 24679)
@@ -1115,17 +1115,14 @@
lib lib/kdb
- lib/crypto lib/crypto/krb lib/crypto/krb/crc32 lib/crypto/$CRYPTO_IMPL/des
- lib/crypto/krb/dk lib/crypto/$CRYPTO_IMPL/enc_provider
- lib/crypto/$CRYPTO_IMPL/hash_provider lib/crypto/krb/checksum
- lib/crypto/krb/prf lib/crypto/$CRYPTO_IMPL
+ lib/crypto lib/crypto/krb lib/crypto/$CRYPTO_IMPL
+ lib/crypto/$CRYPTO_IMPL/enc_provider
+ lib/crypto/$CRYPTO_IMPL/hash_provider
+ lib/crypto/$CRYPTO_IMPL/des
lib/crypto/$CRYPTO_IMPL/md4 lib/crypto/$CRYPTO_IMPL/md5
- lib/crypto/krb/old lib/crypto/krb/raw
- lib/crypto/$CRYPTO_IMPL/sha1
- lib/crypto/$CRYPTO_IMPL/sha2
- lib/crypto/krb/arcfour
- lib/crypto/$CRYPTO_IMPL/aes
- lib/crypto/$CRYPTO_IMPL/camellia lib/crypto/crypto_tests
+ lib/crypto/$CRYPTO_IMPL/sha1 lib/crypto/$CRYPTO_IMPL/sha2
+ lib/crypto/$CRYPTO_IMPL/aes lib/crypto/$CRYPTO_IMPL/camellia
+ lib/crypto/crypto_tests
lib/krb5 lib/krb5/error_tables lib/krb5/asn.1 lib/krb5/ccache
dnl lib/krb5/ccache/ccapi
Modified: trunk/src/lib/crypto/Makefile.in
===================================================================
--- trunk/src/lib/crypto/Makefile.in 2011-03-03 15:21:11 UTC (rev 24678)
+++ trunk/src/lib/crypto/Makefile.in 2011-03-05 13:31:02 UTC (rev 24679)
@@ -18,28 +18,18 @@
LIBFINIFUNC=cryptoint_cleanup_library
RELDIR=crypto
-STOBJLISTS=krb/crc32/OBJS.ST krb/dk/OBJS.ST \
- $(CRYPTO_IMPL)/enc_provider/OBJS.ST \
+STOBJLISTS=$(CRYPTO_IMPL)/enc_provider/OBJS.ST \
$(CRYPTO_IMPL)/hash_provider/OBJS.ST \
- krb/checksum/OBJS.ST krb/prf/OBJS.ST \
- krb/old/OBJS.ST krb/raw/OBJS.ST \
$(CRYPTO_IMPL)/md4/OBJS.ST $(CRYPTO_IMPL)/md5/OBJS.ST \
- $(CRYPTO_IMPL)/sha1/OBJS.ST \
- $(CRYPTO_IMPL)/sha2/OBJS.ST \
- krb/arcfour/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=krb/crc32/OBJS.ST krb/dk/OBJS.ST \
- $(CRYPTO_IMPL)/enc_provider/OBJS.ST \
+SUBDIROBJLISTS=$(CRYPTO_IMPL)/enc_provider/OBJS.ST \
$(CRYPTO_IMPL)/hash_provider/OBJS.ST \
- krb/checksum/OBJS.ST krb/prf/OBJS.ST \
- krb/old/OBJS.ST krb/raw/OBJS.ST \
$(CRYPTO_IMPL)/md4/OBJS.ST $(CRYPTO_IMPL)/md5/OBJS.ST \
- $(CRYPTO_IMPL)/sha1/OBJS.ST \
- $(CRYPTO_IMPL)/sha2/OBJS.ST \
- krb/arcfour/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
@@ -57,8 +47,8 @@
SHLIB_RDIRS=$(KRB5_LIBDIR)
##DOS##LIBNAME=$(OUTPRE)crypto.lib
-##DOS##OBJFILEDEP=$(OUTPRE)crc32.lst $(OUTPRE)prf.lst $(OUTPRE)checksum.lst $(OUTPRE)krb.lst $(OUTPRE)old.lst $(OUTPRE)raw.lst $(OUTPRE)arcfour.lst $(OUTPRE)dk.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)crc32.lst @$(OUTPRE)prf.lst @$(OUTPRE)checksum.lst @$(OUTPRE)krb.lst @$(OUTPRE)old.lst @$(OUTPRE)raw.lst @$(OUTPRE)arcfour.lst @$(OUTPRE)dk.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##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
Copied: trunk/src/lib/crypto/crypto_tests/CRC.pm (from rev 24673, trunk/src/lib/crypto/krb/crc32/CRC.pm)
===================================================================
--- trunk/src/lib/crypto/crypto_tests/CRC.pm (rev 0)
+++ trunk/src/lib/crypto/crypto_tests/CRC.pm 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,156 @@
+# Copyright 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.
+
+package CRC;
+
+# CRC: implement a CRC using the Poly package (yes this is slow)
+#
+# message M(x) = m_0 * x^0 + m_1 * x^1 + ... + m_(k-1) * x^(k-1)
+# generator P(x) = p_0 * x^0 + p_1 * x^1 + ... + p_n * x^n
+# remainder R(x) = r_0 * x^0 + r_1 * x^1 + ... + r_(n-1) * x^(n-1)
+#
+# R(x) = (x^n * M(x)) % P(x)
+#
+# Note that if F(x) = x^n * M(x) + R(x), then F(x) = 0 mod P(x) .
+#
+# In MIT Kerberos 5, R(x) is taken as the CRC, as opposed to what
+# ISO 3309 does.
+#
+# ISO 3309 adds a precomplement and a postcomplement.
+#
+# The ISO 3309 postcomplement is of the form
+#
+# A(x) = x^0 + x^1 + ... + x^(n-1) .
+#
+# The ISO 3309 precomplement is of the form
+#
+# B(x) = x^k * A(x) .
+#
+# The ISO 3309 FCS is then
+#
+# (x^n * M(x)) % P(x) + B(x) % P(x) + A(x) ,
+#
+# which is equivalent to
+#
+# (x^n * M(x) + B(x)) % P(x) + A(x) .
+#
+# In ISO 3309, the transmitted frame is
+#
+# F'(x) = x^n * M(x) + R(x) + R'(x) + A(x) ,
+#
+# where
+#
+# R'(x) = B(x) % P(x) .
+#
+# Note that this means that if a new remainder is computed over the
+# frame F'(x) (treating F'(x) as the new M(x)), it will be equal to a
+# constant.
+#
+# F'(x) = 0 + R'(x) + A(x) mod P(x) ,
+#
+# then
+#
+# (F'(x) + x^k * A(x)) * x^n
+#
+# = ((R'(x) + A(x)) + x^k * A(x)) * x^n mod P(x)
+#
+# = (x^k * A(x) + A(x) + x^k * A(x)) * x^n mod P(x)
+#
+# = (0 + A(x)) * x^n mod P(x)
+#
+# Note that (A(x) * x^n) % P(x) is a constant, and that this result
+# depends on B(x) being x^k * A(x).
+
+use Carp;
+use Poly;
+
+sub new {
+ my $self = shift;
+ my $class = ref($self) || $self;
+ my %args = @_;
+ $self = {bitsendian => "little"};
+ bless $self, $class;
+ $self->setpoly($args{"Poly"}) if exists $args{"Poly"};
+ $self->bitsendian($args{"bitsendian"})
+ if exists $args{"bitsendian"};
+ $self->{precomp} = $args{precomp} if exists $args{precomp};
+ $self->{postcomp} = $args{postcomp} if exists $args{postcomp};
+ return $self;
+}
+
+sub setpoly {
+ my $self = shift;
+ my($arg) = @_;
+ croak "need a polynomial" if !$arg->isa("Poly");
+ $self->{Poly} = $arg;
+ return $self;
+}
+
+sub crc {
+ my $self = shift;
+ my $msg = Poly->new(@_);
+ my($order, $r, $precomp);
+ $order = $self->{Poly}->order;
+ # B(x) = x^k * precomp
+ $precomp = $self->{precomp} ?
+ $self->{precomp} * Poly->powers2poly(scalar(@_)) : Poly->new;
+ # R(x) = (x^n * M(x)) % P(x)
+ $r = ($msg * Poly->powers2poly($order)) % $self->{Poly};
+ # B(x) % P(x)
+ $r += $precomp % $self->{Poly};
+ $r += $self->{postcomp} if exists $self->{postcomp};
+ return $r;
+}
+
+# endianness of bits of each octet
+#
+# Note that the message is always treated as being sent in big-endian
+# octet order.
+#
+# Usually, the message will be treated as bits being little-endian,
+# since that is the common case for serial implementations that
+# present data in octets; e.g., most UARTs shift octets onto the line
+# in little-endian order, and protocols such as ISO 3309, V.42,
+# etc. treat individual octets as being sent LSB-first.
+
+sub bitsendian {
+ my $self = shift;
+ my($arg) = @_;
+ croak "bad bit endianness" if $arg !~ /big|little/;
+ $self->{bitsendian} = $arg;
+ return $self;
+}
+
+sub crcstring {
+ my $self = shift;
+ my($arg) = @_;
+ my($packstr, @m);
+ {
+ $packstr = "B*", last if $self->{bitsendian} =~ /big/;
+ $packstr = "b*", last if $self->{bitsendian} =~ /little/;
+ croak "bad bit endianness";
+ };
+ @m = split //, unpack $packstr, $arg;
+ return $self->crc(@m);
+}
+
+1;
Copied: trunk/src/lib/crypto/crypto_tests/Poly.pm (from rev 24673, trunk/src/lib/crypto/krb/crc32/Poly.pm)
===================================================================
--- trunk/src/lib/crypto/crypto_tests/Poly.pm (rev 0)
+++ trunk/src/lib/crypto/crypto_tests/Poly.pm 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,182 @@
+# Copyright 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.
+
+package Poly;
+
+# Poly: implements some basic operations on polynomials in the field
+# of integers (mod 2).
+#
+# The rep is an array of coefficients, highest order term first.
+#
+# This is rather slow at the moment.
+
+use overload
+ '+' => \&add,
+ '-' => \&add,
+ '*' => \&mul,
+ '%' => sub {$_[2] ? mod($_[1], $_[0]) : mod($_[0], $_[1])},
+ '/' => sub { $_[2] ? scalar(div($_[1], $_[0]))
+ : scalar(div($_[0], $_[1])) },
+ '<=>' => sub {$_[2] ? pcmp($_[1], $_[0]) : pcmp($_[0], $_[1])},
+ '""' => \&str
+;
+
+use Carp;
+
+# doesn't do much beyond normalize and bless
+sub new {
+ my $this = shift;
+ my $class = ref($this) || $this;
+ my(@x) = @_;
+ return bless [norm(@x)], $class;
+}
+
+# stringified P(x)
+sub pretty {
+ my(@x) = @{+shift};
+ my $n = @x;
+ local $_;
+ return "0" if !@x;
+ return join " + ", map {$n--; $_ ? ("x^$n") : ()} @x;
+}
+
+sub print {
+ my $self = shift;
+ print $self->pretty, "\n";
+}
+
+# This assumes normalization.
+sub order {
+ my $self = shift;
+ return $#{$self};
+}
+
+sub str {
+ return overload::StrVal($_[0]);
+}
+
+# strip leading zero coefficients
+sub norm {
+ my(@x) = @_;
+ shift @x while @x && !$x[0];
+ return @x;
+}
+
+# multiply $self by the single term of power $n
+sub multerm {
+ my($self, $n) = @_;
+ return $self->new(@$self, (0) x $n);
+}
+
+# This is really an order comparison; different polys of same order
+# compare equal. It also assumes prior normalization.
+sub pcmp {
+ my @x = @{+shift};
+ my @y = @{+shift};
+ return @x <=> @y;
+}
+
+# convenience constructor; takes list of non-zero terms
+sub powers2poly
+{
+ my $self = shift;
+ my $poly = $self->new;
+ my $n;
+ foreach $n (@_) {
+ $poly += $one->multerm($n);
+ }
+ return $poly;
+}
+
+sub add {
+ my $self = shift;
+ my @x = @$self;
+ my @y = @{+shift};
+ my @r;
+ unshift @r, (pop @x || 0) ^ (pop @y || 0)
+ while @x || @y;
+ return $self->new(@r);
+}
+
+sub mul {
+ my($self) = shift;
+ my @y = @{+shift};
+ my $r = $self->new;
+ my $power = 0;
+ while (@y) {
+ $r += $self->multerm($power) if pop @y;
+ $power++;
+ }
+ return $r;
+}
+
+sub oldmod {
+ my($self, $div) = @_;
+ my @num = @$self;
+ my @div = @$div;
+ my $r = $self->new(splice @num, 0, @div);
+ do {
+ push @$r, shift @num while @num && $r < $div;
+ $r += $div if $r >= $div;
+ } while @num;
+ return $r;
+}
+
+sub div {
+ my($self, $div) = @_;
+ my $q = $self->new;
+ my $r = $self->new(@$self);
+ my $one = $self->new(1);
+ my ($tp, $power);
+ croak "divide by zero" if !@$div;
+ while ($div <= $r) {
+ $power = 0;
+ $power++ while ($tp = $div->multerm($power)) < $r;
+ $q += $one->multerm($power);
+ $r -= $tp;
+ }
+ return wantarray ? ($q, $r) : $q;
+}
+
+sub mod {
+ (&div)[1];
+}
+
+# bits and octets both big-endian
+sub hex {
+ my @x = @{+shift};
+ my $minwidth = shift || 32;
+ unshift @x, 0 while @x % 8 || @x < $minwidth;
+ return unpack "H*", pack "B*", join "", @x;
+}
+
+# bit-reversal of above
+sub revhex {
+ my @x = @{+shift};
+ my $minwidth = shift || 32;
+ unshift @x, 0 while @x % 8 || @x < $minwidth;
+ return unpack "H*", pack "B*", join "", reverse @x;
+}
+
+$one = Poly->new(1);
+
+1;
Copied: trunk/src/lib/crypto/crypto_tests/crc.pl (from rev 24673, trunk/src/lib/crypto/krb/crc32/crc.pl)
===================================================================
--- trunk/src/lib/crypto/crypto_tests/crc.pl (rev 0)
+++ trunk/src/lib/crypto/crypto_tests/crc.pl 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,111 @@
+# Copyright 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.
+
+use CRC;
+
+print "*** crudely testing polynomial functions ***\n";
+
+$x = Poly->new(1,1,1,1);
+$y = Poly->new(1,1);
+print "x = @{[$x->pretty]}\ny = @{[$y->pretty]}\n";
+$q = $x / $y;
+$r = $x % $y;
+print $x->pretty, " = (", $y->pretty , ") * (", $q->pretty,
+ ") + ", $r->pretty, "\n";
+$q = $y / $x;
+$r = $y % $x;
+print "y / x = @{[$q->pretty]}\ny % x = @{[$r->pretty]}\n";
+
+# ISO 3309 32-bit FCS polynomial
+$fcs32 = Poly->powers2poly(32,26,23,22,16,12,11,10,8,7,5,4,2,1,0);
+print "fcs32 = ", $fcs32->pretty, "\n";
+
+$crc = CRC->new(Poly => $fcs32, bitsendian => "little");
+
+print "\n";
+
+print "*** little endian, no complementation ***\n";
+for ($i = 0; $i < 256; $i++) {
+ $r = $crc->crcstring(pack "C", $i);
+ printf ("%02x: ", $i) if !($i % 8);
+ print ($r->revhex, ($i % 8 == 7) ? "\n" : " ");
+}
+
+print "\n";
+
+print "*** little endian, 4 bits, no complementation ***\n";
+for ($i = 0; $i < 16; $i++) {
+ @m = (split //, unpack "b*", pack "C", $i)[0..3];
+ $r = $crc->crc(@m);
+ printf ("%02x: ", $i) if !($i % 8);
+ print ($r->revhex, ($i % 8 == 7) ? "\n" : " ");
+}
+
+print "\n";
+
+print "*** test vectors for t_crc.c, little endian ***\n";
+for ($i = 1; $i <= 4; $i *=2) {
+ for ($j = 0; $j < $i * 8; $j++) {
+ @m = split //, unpack "b*", pack "V", 1 << $j;
+ splice @m, $i * 8;
+ $r = $crc->crc(@m);
+ $m = unpack "H*", pack "b*", join("", @m);
+ print "{HEX, \"$m\", 0x", $r->revhex, "},\n";
+ }
+}
+ at m = ("foo", "test0123456789",
+ "MASSACHVSETTS INSTITVTE OF TECHNOLOGY");
+foreach $m (@m) {
+ $r = $crc->crcstring($m);
+ print "{STR, \"$m\", 0x", $r->revhex, "},\n";
+}
+__END__
+
+print "*** big endian, no complementation ***\n";
+for ($i = 0; $i < 256; $i++) {
+ $r = $crc->crcstring(pack "C", $i);
+ printf ("%02x: ", $i) if !($i % 8);
+ print ($r->hex, ($i % 8 == 7) ? "\n" : " ");
+}
+
+# all ones polynomial of order 31
+$ones = Poly->new((1) x 32);
+
+print "*** big endian, ISO-3309 style\n";
+$crc = CRC->new(Poly => $fcs32,
+ bitsendian => "little",
+ precomp => $ones,
+ postcomp => $ones);
+for ($i = 0; $i < 256; $i++) {
+ $r = $crc->crcstring(pack "C", $i);
+ print ($r->hex, ($i % 8 == 7) ? "\n" : " ");
+}
+
+for ($i = 0; $i < 0; $i++) {
+ $x = Poly->new((1) x 32, (0) x $i);
+ $y = Poly->new((1) x 32);
+ $f = ($x % $fcs32) + $y;
+ $r = (($f + $x) * Poly->powers2poly(32)) % $fcs32;
+ @out = @$r;
+ unshift @out, 0 while @out < 32;
+ print @out, "\n";
+}
Modified: trunk/src/lib/crypto/krb/Makefile.in
===================================================================
--- trunk/src/lib/crypto/krb/Makefile.in 2011-03-03 15:21:11 UTC (rev 24678)
+++ trunk/src/lib/crypto/krb/Makefile.in 2011-03-05 13:31:02 UTC (rev 24679)
@@ -1,6 +1,5 @@
mydir=lib$(S)crypto$(S)krb
BUILDTOP=$(REL)..$(S)..$(S)..
-SUBDIRS= arcfour checksum crc32 dk prf old raw
LOCALINCLUDES = -I$(srcdir) -I$(srcdir)/../$(CRYPTO_IMPL)
RUN_SETUP = @KRB5_RUN_ENV@
PROG_LIBPATH=-L$(TOPLIBD)
@@ -18,20 +17,34 @@
aead.o \
block_size.o \
cf2.o \
+ checksum_cbc.o \
+ checksum_confounder.o \
+ checksum_dk_cmac.o \
+ checksum_dk_hmac.o \
+ checksum_hmac_md5.o \
+ checksum_unkeyed.o \
checksum_length.o \
cksumtype_to_string.o \
cksumtypes.o \
+ cmac.o \
coll_proof_cksum.o \
combine_keys.o \
+ crc32.o \
crypto_length.o \
crypto_libinit.o \
default_state.o \
decrypt.o \
decrypt_iov.o \
+ derive.o \
encrypt.o \
encrypt_iov.o \
encrypt_length.o \
enctype_util.o \
+ enc_dk_cmac.o \
+ enc_dk_hmac.o \
+ enc_old.o \
+ enc_raw.o \
+ enc_rc4.o \
etypes.o \
key.o \
keyblocks.o \
@@ -45,9 +58,16 @@
nfold.o \
old_api_glue.o \
prf.o \
+ prf_cmac.o \
+ prf_des.o \
+ prf_dk.o \
+ prf_rc4.o \
prng.o \
prng_$(PRNG_ALG).o \
random_to_key.o \
+ s2k_des.o \
+ s2k_pbkdf2.o \
+ s2k_rc4.o \
state.o \
string_to_cksumtype.o \
string_to_key.o \
@@ -64,6 +84,7 @@
$(OUTPRE)cksumtypes.$(OBJEXT) \
$(OUTPRE)coll_proof_cksum.$(OBJEXT) \
$(OUTPRE)combine_keys.$(OBJEXT) \
+ $(OUTPRE)crc_32.$(OBJEXT) \
$(OUTPRE)crypto_length.$(OBJEXT) \
$(OUTPRE)crypto_libinit.$(OBJEXT) \
$(OUTPRE)default_state.$(OBJEXT) \
@@ -72,7 +93,12 @@
$(OUTPRE)encrypt.$(OBJEXT) \
$(OUTPRE)encrypt_iov.$(OBJEXT) \
$(OUTPRE)encrypt_length.$(OBJEXT) \
- $(OUTPRE)enctype_util.$(OBJEXT) \
+ $(OUTPRE)enctype_util.$(OBJEXT) \
+ $(OUTPRE)enc_dk_cmac.$(OBJEXT) \
+ $(OUTPRE)enc_dk_hmac.$(OBJEXT) \
+ $(OUTPRE)enc_old.$(OBJEXT) \
+ $(OUTPRE)enc_raw.$(OBJEXT) \
+ $(OUTPRE)enc_rc4.$(OBJEXT) \
$(OUTPRE)etypes.$(OBJEXT) \
$(OUTPRE)key.$(OBJEXT) \
$(OUTPRE)keyblocks.$(OBJEXT) \
@@ -85,10 +111,17 @@
$(OUTPRE)mandatory_sumtype.$(OBJEXT) \
$(OUTPRE)nfold.$(OBJEXT) \
$(OUTPRE)old_api_glue.$(OBJEXT) \
- $(OUTPRE)prf.$(OBJEXT) \
+ $(OUTPRE)prf.$(OBJEXT) \
+ $(OUTPRE)prf_cmac.$(OBJEXT) \
+ $(OUTPRE)prf_des.$(OBJEXT) \
+ $(OUTPRE)prf_dk.$(OBJEXT) \
+ $(OUTPRE)prf_rc4.$(OBJEXT) \
$(OUTPRE)prng.$(OBJEXT) \
$(OUTPRE)prng_$(PRNG_ALG).$(OBJEXT) \
$(OUTPRE)random_to_key.$(OBJEXT) \
+ $(OUTPRE)s2k_des.$(OBJEXT) \
+ $(OUTPRE)s2k_pbkdf2.$(OBJEXT) \
+ $(OUTPRE)s2k_rc4.$(OBJEXT) \
$(OUTPRE)state.$(OBJEXT) \
$(OUTPRE)string_to_cksumtype.$(OBJEXT) \
$(OUTPRE)string_to_key.$(OBJEXT) \
@@ -104,6 +137,7 @@
$(srcdir)/cksumtypes.c \
$(srcdir)/coll_proof_cksum.c \
$(srcdir)/combine_keys.c \
+ $(srcdir)/crc32.c \
$(srcdir)/crypto_length.c \
$(srcdir)/crypto_libinit.c \
$(srcdir)/default_state.c \
@@ -113,6 +147,11 @@
$(srcdir)/encrypt_iov.c \
$(srcdir)/encrypt_length.c \
$(srcdir)/enctype_util.c \
+ $(srcdir)/enc_dk_cmac.c \
+ $(srcdir)/enc_dk_hmac.c \
+ $(srcdir)/enc_old.c \
+ $(srcdir)/enc_raw.c \
+ $(srcdir)/enc_rc4.c \
$(srcdir)/etypes.c \
$(srcdir)/key.c \
$(srcdir)/keyblocks.c \
@@ -125,11 +164,18 @@
$(srcdir)/mandatory_sumtype.c \
$(srcdir)/nfold.c \
$(srcdir)/old_api_glue.c \
- $(srcdir)/prf.c \
+ $(srcdir)/prf.c \
+ $(srcdir)/prf_cmac.c \
+ $(srcdir)/prf_des.c \
+ $(srcdir)/prf_dk.c \
+ $(srcdir)/prf_rc4.c \
$(srcdir)/prng.c \
$(srcdir)/prng_$(PRNG_ALG).c \
$(srcdir)/cf2.c \
$(srcdir)/random_to_key.c \
+ $(srcdir)/s2k_des.c \
+ $(srcdir)/s2k_pbkdf2.c \
+ $(srcdir)/s2k_rc4.c \
$(srcdir)/state.c \
$(srcdir)/string_to_cksumtype.c \
$(srcdir)/string_to_key.c \
@@ -138,12 +184,6 @@
$(srcdir)/verify_checksum.c \
$(srcdir)/verify_checksum_iov.c
-STOBJLISTS=arcfour/OBJS.ST checksum/OBJS.ST crc32/OBJS.ST \
- dk/OBJS.ST prf/OBJS.ST old/OBJS.ST raw/OBJS.ST OBJS.ST
-
-SUBDIROBJLISTS=arcfour/OBJS.ST checksum/OBJS.ST crc32/OBJS.ST \
- dk/OBJS.ST prf/OBJS.ST old/OBJS.ST raw/OBJS.ST
-
##DOS##LIBOBJS = $(OBJS)
all-unix:: all-libobjs
Copied: trunk/src/lib/crypto/krb/checksum_cbc.c (from rev 24677, trunk/src/lib/crypto/krb/checksum/cbc.c)
===================================================================
--- trunk/src/lib/crypto/krb/checksum_cbc.c (rev 0)
+++ trunk/src/lib/crypto/krb/checksum_cbc.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,42 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/checksum/cbc.c
+ *
+ * Copyright (C) 2009 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 checksum, which computes the ivec resulting from CBC encryption of the
+ * input.
+ */
+
+#include "crypto_int.h"
+
+krb5_error_code
+krb5int_cbc_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ if (ctp->enc->cbc_mac == NULL)
+ return KRB5_CRYPTO_INTERNAL;
+ return ctp->enc->cbc_mac(key, data, num_data, NULL, output);
+}
Copied: trunk/src/lib/crypto/krb/checksum_confounder.c (from rev 24677, trunk/src/lib/crypto/krb/checksum/confounder.c)
===================================================================
--- trunk/src/lib/crypto/krb/checksum_confounder.c (rev 0)
+++ trunk/src/lib/crypto/krb/checksum_confounder.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,159 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/checksum/confounder.c
+ *
+ * Copyright (C) 2009 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.
+ *
+ * Confounder checksum implementation, using tokens of the form:
+ * enc(xorkey, confounder | hash(confounder | data))
+ * where xorkey is the key XOR'd with 0xf0 bytes.
+ */
+
+#include "crypto_int.h"
+
+/* Derive a key by XOR with 0xF0 bytes. */
+static krb5_error_code
+mk_xorkey(krb5_key origkey, krb5_key *xorkey)
+{
+ krb5_error_code retval = 0;
+ unsigned char *xorbytes;
+ krb5_keyblock xorkeyblock;
+ size_t i = 0;
+
+ xorbytes = malloc(origkey->keyblock.length);
+ if (xorbytes == NULL)
+ return ENOMEM;
+ memcpy(xorbytes, origkey->keyblock.contents, origkey->keyblock.length);
+ for (i = 0; i < origkey->keyblock.length; i++)
+ xorbytes[i] ^= 0xf0;
+
+ /* Do a shallow copy here. */
+ xorkeyblock = origkey->keyblock;
+ xorkeyblock.contents = xorbytes;
+
+ retval = krb5_k_create_key(0, &xorkeyblock, xorkey);
+ zapfree(xorbytes, sizeof(xorbytes));
+ return retval;
+}
+
+krb5_error_code
+krb5int_confounder_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ krb5_error_code ret;
+ krb5_data conf, hashval;
+ krb5_key xorkey = NULL;
+ krb5_crypto_iov *hash_iov, iov;
+ size_t blocksize = ctp->enc->block_size, hashsize = ctp->hash->hashsize;
+
+ /* Partition the output buffer into confounder and hash. */
+ conf = make_data(output->data, blocksize);
+ hashval = make_data(output->data + blocksize, hashsize);
+
+ /* Create the confounder. */
+ ret = krb5_c_random_make_octets(NULL, &conf);
+ if (ret != 0)
+ return ret;
+
+ ret = mk_xorkey(key, &xorkey);
+ if (ret)
+ return ret;
+
+ /* Hash the confounder, then the input data. */
+ hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
+ if (hash_iov == NULL)
+ goto cleanup;
+ hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ hash_iov[0].data = conf;
+ memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
+ ret = ctp->hash->hash(hash_iov, num_data + 1, &hashval);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Confounder and hash are in output buffer; encrypt them in place. */
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *output;
+ ret = ctp->enc->encrypt(xorkey, NULL, &iov, 1);
+
+cleanup:
+ free(hash_iov);
+ krb5_k_free_key(NULL, xorkey);
+ return ret;
+}
+
+krb5_error_code krb5int_confounder_verify(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data,
+ size_t num_data,
+ const krb5_data *input,
+ krb5_boolean *valid)
+{
+ krb5_error_code ret;
+ unsigned char *plaintext = NULL;
+ krb5_key xorkey = NULL;
+ krb5_data computed = empty_data();
+ krb5_crypto_iov *hash_iov = NULL, iov;
+ size_t blocksize = ctp->enc->block_size, hashsize = ctp->hash->hashsize;
+
+ plaintext = k5alloc(input->length, &ret);
+ if (plaintext == NULL)
+ return ret;
+
+ ret = mk_xorkey(key, &xorkey);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Decrypt the input checksum. */
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = make_data(plaintext, input->length);
+ memcpy(plaintext, input->data, input->length);
+ ret = ctp->enc->decrypt(xorkey, NULL, &iov, 1);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Hash the confounder, then the input data. */
+ hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
+ if (hash_iov == NULL)
+ goto cleanup;
+ hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ hash_iov[0].data = make_data(plaintext, blocksize);
+ memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
+ ret = alloc_data(&computed, hashsize);
+ if (ret != 0)
+ goto cleanup;
+ ret = ctp->hash->hash(hash_iov, num_data + 1, &computed);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Compare the decrypted hash to the computed one. */
+ *valid = (memcmp(plaintext + blocksize, computed.data, hashsize) == 0);
+
+cleanup:
+ zapfree(plaintext, input->length);
+ zapfree(computed.data, hashsize);
+ free(hash_iov);
+ krb5_k_free_key(NULL, xorkey);
+ return ret;
+}
Copied: trunk/src/lib/crypto/krb/checksum_dk_cmac.c (from rev 24677, trunk/src/lib/crypto/krb/dk/checksum_cmac.c)
===================================================================
--- trunk/src/lib/crypto/krb/checksum_dk_cmac.c (rev 0)
+++ trunk/src/lib/crypto/krb/checksum_dk_cmac.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,62 @@
+/*
+ * lib/crypto/krb/dk/checksum_cmac.c
+ *
+ * Copyright 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"
+
+#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
+
+#ifdef CAMELLIA
+
+krb5_error_code
+krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ const struct krb5_enc_provider *enc = ctp->enc;
+ krb5_error_code ret;
+ unsigned char constantdata[K5CLENGTH];
+ krb5_data datain;
+ krb5_key kc;
+
+ /* Derive the key. */
+ datain = make_data(constantdata, K5CLENGTH);
+ store_32_be(usage, constantdata);
+ constantdata[4] = (char) 0x99;
+ ret = krb5int_derive_key(enc, key, &kc, &datain, DERIVE_SP800_108_CMAC);
+ if (ret != 0)
+ return ret;
+
+ /* Hash the data. */
+ ret = krb5int_cmac_checksum(enc, kc, data, num_data, output);
+ if (ret != 0)
+ memset(output->data, 0, output->length);
+
+ krb5_k_free_key(NULL, kc);
+ return ret;
+}
+
+#endif /* CAMELLIA */
Copied: trunk/src/lib/crypto/krb/checksum_dk_hmac.c (from rev 24677, trunk/src/lib/crypto/krb/dk/checksum_hmac.c)
===================================================================
--- trunk/src/lib/crypto/krb/checksum_dk_hmac.c (rev 0)
+++ trunk/src/lib/crypto/krb/checksum_dk_hmac.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,59 @@
+/* -*- 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"
+
+#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
+
+krb5_error_code
+krb5int_dk_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ const struct krb5_enc_provider *enc = ctp->enc;
+ krb5_error_code ret;
+ unsigned char constantdata[K5CLENGTH];
+ krb5_data datain;
+ krb5_key kc;
+
+ /* Derive the key. */
+ datain = make_data(constantdata, K5CLENGTH);
+ store_32_be(usage, constantdata);
+ constantdata[4] = (char) 0x99;
+ ret = krb5int_derive_key(enc, key, &kc, &datain, DERIVE_RFC3961);
+ if (ret)
+ return ret;
+
+ /* Hash the data. */
+ ret = krb5int_hmac(ctp->hash, kc, data, num_data, output);
+ if (ret)
+ memset(output->data, 0, output->length);
+
+ krb5_k_free_key(NULL, kc);
+ return ret;
+}
Copied: trunk/src/lib/crypto/krb/checksum_hmac_md5.c (from rev 24677, trunk/src/lib/crypto/krb/checksum/hmac_md5.c)
===================================================================
--- trunk/src/lib/crypto/krb/checksum_hmac_md5.c (rev 0)
+++ trunk/src/lib/crypto/krb/checksum_hmac_md5.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,93 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/checksum/hmac_md5.c
+ *
+ * Copyright (C) 2009 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.
+ *
+ * Microsoft HMAC-MD5 and MD5-HMAC checksums (see RFC 4757):
+ * HMAC(KS, hash(msusage || input))
+ * KS is HMAC(key, "signaturekey\0") for HMAC-MD5, or just the key for
+ * MD5-HMAC.
+ */
+
+#include "crypto_int.h"
+
+krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data,
+ size_t num_data,
+ krb5_data *output)
+{
+ krb5_keyusage ms_usage;
+ krb5_error_code ret;
+ krb5_keyblock ks, *keyblock;
+ krb5_crypto_iov *hash_iov = NULL, iov;
+ krb5_data ds = empty_data(), hashval = empty_data();
+ char t[4];
+
+ if (key == NULL || key->keyblock.length > ctp->hash->blocksize)
+ return KRB5_BAD_ENCTYPE;
+ if (ctp->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR) {
+ /* Compute HMAC(key, "signaturekey\0") to get the signing key ks. */
+ ret = alloc_data(&ds, ctp->hash->hashsize);
+ if (ret != 0)
+ goto cleanup;
+
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = make_data("signaturekey", 13);
+ ret = krb5int_hmac(ctp->hash, key, &iov, 1, &ds);
+ if (ret)
+ goto cleanup;
+ ks.length = key->keyblock.length;
+ ks.contents = (krb5_octet *) ds.data;
+ keyblock = &ks;
+ } else /* For md5-hmac, just use the key. */
+ keyblock = &key->keyblock;
+
+ /* Compute the MD5 value of the input. */
+ ms_usage = krb5int_arcfour_translate_usage(usage);
+ store_32_le(ms_usage, t);
+ hash_iov = k5alloc((num_data + 1) * sizeof(krb5_crypto_iov), &ret);
+ if (hash_iov == NULL)
+ goto cleanup;
+ hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ hash_iov[0].data = make_data(t, 4);
+ memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov));
+ ret = alloc_data(&hashval, ctp->hash->hashsize);
+ if (ret != 0)
+ goto cleanup;
+ ret = ctp->hash->hash(hash_iov, num_data + 1, &hashval);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Compute HMAC(ks, md5value). */
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = hashval;
+ ret = krb5int_hmac_keyblock(ctp->hash, keyblock, &iov, 1, output);
+
+cleanup:
+ zapfree(ds.data, ds.length);
+ zapfree(hashval.data, hashval.length);
+ free(hash_iov);
+ return ret;
+}
Copied: trunk/src/lib/crypto/krb/checksum_unkeyed.c (from rev 24677, trunk/src/lib/crypto/krb/checksum/unkeyed.c)
===================================================================
--- trunk/src/lib/crypto/krb/checksum_unkeyed.c (rev 0)
+++ trunk/src/lib/crypto/krb/checksum_unkeyed.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,39 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/checksum/unkeyed.c
+ *
+ * Copyright (C) 2009 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.
+ *
+ * Unkeyed hash checksum implementation.
+ */
+
+#include "crypto_int.h"
+
+krb5_error_code
+krb5int_unkeyed_checksum(const struct krb5_cksumtypes *ctp,
+ krb5_key key, krb5_keyusage usage,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ return ctp->hash->hash(data, num_data, output);
+}
Copied: trunk/src/lib/crypto/krb/cmac.c (from rev 24677, trunk/src/lib/crypto/krb/checksum/cmac.c)
===================================================================
--- trunk/src/lib/crypto/krb/cmac.c (rev 0)
+++ trunk/src/lib/crypto/krb/cmac.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,237 @@
+/*
+ * lib/crypto/krb/checksum/cmac.c
+ *
+ * Copyright 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.
+ */
+/*
+ * Portions Copyright (C) The Internet Society (2006).
+ *
+ * This document is subject to the rights, licenses and restrictions
+ * contained in BCP 78, and except as set forth therein, the authors
+ * retain all their rights.
+ *
+ * This document and the information contained herein are provided on an
+ * "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ * OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ * ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ * INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "crypto_int.h"
+
+#ifdef CAMELLIA
+
+#define BLOCK_SIZE 16
+
+static unsigned char const_Rb[BLOCK_SIZE] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
+};
+
+static void
+xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
+{
+ int z;
+
+ for (z = 0; z < BLOCK_SIZE / 4; z++) {
+ unsigned char *aptr = &a[z * 4];
+ unsigned char *bptr = &b[z * 4];
+ unsigned char *outptr = &out[z * 4];
+
+ store_32_n(load_32_n(aptr) ^ load_32_n(bptr), outptr);
+ }
+}
+
+static void
+leftshift_onebit(unsigned char *input, unsigned char *output)
+{
+ int i;
+ unsigned char overflow = 0;
+
+ for (i = BLOCK_SIZE - 1; i >= 0; i--) {
+ output[i] = input[i] << 1;
+ output[i] |= overflow;
+ overflow = (input[i] & 0x80) ? 1 : 0;
+ }
+}
+
+/* Generate subkeys K1 and K2 as described in RFC 4493 figure 2.2. */
+static krb5_error_code
+generate_subkey(const struct krb5_enc_provider *enc,
+ krb5_key key,
+ unsigned char *K1,
+ unsigned char *K2)
+{
+ unsigned char L[BLOCK_SIZE];
+ unsigned char tmp[BLOCK_SIZE];
+ krb5_data d;
+ krb5_error_code ret;
+
+ /* L := encrypt(K, const_Zero) */
+ memset(L, 0, sizeof(L));
+ d = make_data(L, BLOCK_SIZE);
+ ret = encrypt_block(enc, key, &d);
+ if (ret != 0)
+ return ret;
+
+ /* K1 := (MSB(L) == 0) ? L << 1 : (L << 1) XOR const_Rb */
+ if ((L[0] & 0x80) == 0) {
+ leftshift_onebit(L, K1);
+ } else {
+ leftshift_onebit(L, tmp);
+ xor_128(tmp, const_Rb, K1);
+ }
+
+ /* K2 := (MSB(K1) == 0) ? K1 << 1 : (K1 << 1) XOR const_Rb */
+ if ((K1[0] & 0x80) == 0) {
+ leftshift_onebit(K1, K2);
+ } else {
+ leftshift_onebit(K1, tmp);
+ xor_128(tmp, const_Rb, K2);
+ }
+
+ return 0;
+}
+
+/* Pad out lastb with a 1 bit followed by 0 bits, placing the result in pad. */
+static void
+padding(unsigned char *lastb, unsigned char *pad, int length)
+{
+ int j;
+
+ /* original last block */
+ for (j = 0; j < BLOCK_SIZE; j++) {
+ if (j < length) {
+ pad[j] = lastb[j];
+ } else if (j == length) {
+ pad[j] = 0x80;
+ } else {
+ pad[j] = 0x00;
+ }
+ }
+}
+
+/*
+ * Implementation of CMAC algorithm. When used with AES, this function
+ * is compatible with RFC 4493 figure 2.3.
+ */
+krb5_error_code
+krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ unsigned char Y[BLOCK_SIZE], M_last[BLOCK_SIZE], padded[BLOCK_SIZE];
+ unsigned char K1[BLOCK_SIZE], K2[BLOCK_SIZE];
+ unsigned char input[BLOCK_SIZE];
+ unsigned int n, i, flag;
+ krb5_error_code ret;
+ struct iov_block_state iov_state;
+ unsigned int length;
+ krb5_crypto_iov iov[1];
+ krb5_data d;
+
+ assert(enc->cbc_mac != NULL);
+
+ if (enc->block_size != BLOCK_SIZE)
+ return KRB5_BAD_MSIZE;
+
+ for (i = 0, length = 0; i < num_data; i++) {
+ const krb5_crypto_iov *piov = &data[i];
+
+ if (SIGN_IOV(piov))
+ length += piov->data.length;
+ }
+
+ /* Step 1. */
+ ret = generate_subkey(enc, key, K1, K2);
+ if (ret != 0)
+ return ret;
+
+ /* Step 2. */
+ n = (length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+ /* Step 3. */
+ if (n == 0) {
+ n = 1;
+ flag = 0;
+ } else {
+ flag = ((length % BLOCK_SIZE) == 0);
+ }
+
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[0].data = make_data(input, BLOCK_SIZE);
+
+ /* Step 5 (we'll do step 4 in a bit). */
+ memset(Y, 0, BLOCK_SIZE);
+ d = make_data(Y, BLOCK_SIZE);
+
+ /* Step 6 (all but last block). */
+ IOV_BLOCK_STATE_INIT(&iov_state);
+ iov_state.include_sign_only = 1;
+ for (i = 0; i < n - 1; i++) {
+ krb5int_c_iov_get_block(input, BLOCK_SIZE, data, num_data, &iov_state);
+
+ ret = enc->cbc_mac(key, iov, 1, &d, &d);
+ if (ret != 0)
+ return ret;
+ }
+
+ /* Step 4. */
+ krb5int_c_iov_get_block(input, BLOCK_SIZE, data, num_data, &iov_state);
+ if (flag) {
+ /* last block is complete block */
+ xor_128(input, K1, M_last);
+ } else {
+ padding(input, padded, length % BLOCK_SIZE);
+ xor_128(padded, K2, M_last);
+ }
+
+ /* Step 6 (last block). */
+ iov[0].data = make_data(M_last, BLOCK_SIZE);
+ ret = enc->cbc_mac(key, iov, 1, &d, &d);
+ if (ret != 0)
+ return ret;
+
+ assert(output->length >= d.length);
+
+ output->length = d.length;
+ memcpy(output->data, d.data, d.length);
+
+ return 0;
+}
+
+#else /* CAMELLIA */
+
+/* This won't be used, but is still in the export table. */
+
+krb5_error_code
+krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key,
+ const krb5_crypto_iov *data, size_t num_data,
+ krb5_data *output)
+{
+ return EINVAL;
+}
+
+#endif /* CAMELLIA */
Copied: trunk/src/lib/crypto/krb/crc32.c (from rev 24677, trunk/src/lib/crypto/krb/crc32/crc32.c)
===================================================================
--- trunk/src/lib/crypto/krb/crc32.c (rev 0)
+++ trunk/src/lib/crypto/krb/crc32.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,166 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/crc32/crc.c
+ *
+ * Copyright 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.
+ *
+ *
+ * CRC-32/AUTODIN-II routines
+ */
+
+#include "crypto_int.h"
+
+/* This table and block of comments are taken from code labeled: */
+/*
+ * Copyright (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+
+/* First, the polynomial itself and its table of feedback terms. The */
+/* polynomial is */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in */
+/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
+/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
+/* the MSB being 1. */
+
+/* Note that the usual hardware shift register implementation, which */
+/* is what we're using (we're merely optimizing it by doing eight-bit */
+/* chunks at a time) shifts bits into the lowest-order term. In our */
+/* implementation, that means shifting towards the right. Why do we */
+/* do it this way? Because the calculated CRC must be transmitted in */
+/* order from highest-order term to lowest-order term. UARTs transmit */
+/* characters in order from LSB to MSB. By storing the CRC this way, */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part. Reception works similarly. */
+
+/* The feedback terms table consists of 256, 32-bit entries. Notes: */
+/* */
+/* 1. The table can be generated at runtime if desired; code to do so */
+/* is shown later. It might not be obvious, but the feedback */
+/* terms simply represent the results of eight shift/xor opera- */
+/* tions for all combinations of data and CRC register values. */
+/* */
+/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
+/* be they sixteen or thirty-two bits wide. You simply choose the */
+/* appropriate table. Alternatively, because the table can be */
+/* generated at runtime, you can start by generating the table for */
+/* the polynomial in question and use exactly the same "updcrc", */
+/* if your application needn't simultaneously handle two CRC */
+/* polynomials. (Note, however, that XMODEM is strange.) */
+/* */
+/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
+/* of course, 32-bit entries work OK if the high 16 bits are zero. */
+/* */
+/* 4. The values must be right-shifted by eight bits by the "updcrc" */
+/* logic; the shift must be unsigned (bring in zeroes). On some */
+/* hardware you could probably optimize the shift in assembler by */
+/* using byte-swap instructions. */
+
+static u_long const crc_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+void
+mit_crc32(krb5_pointer in, size_t in_length, unsigned long *cksum)
+{
+ register u_char *data;
+ register u_long c = *cksum;
+ register int idx;
+ size_t i;
+
+ data = (u_char *)in;
+ for (i = 0; i < in_length; i++) {
+ idx = (int) (data[i] ^ c);
+ idx &= 0xff;
+ c >>= 8;
+ c ^= crc_table[idx];
+ }
+
+ *cksum = c;
+}
Modified: trunk/src/lib/crypto/krb/deps
===================================================================
--- trunk/src/lib/crypto/krb/deps 2011-03-03 15:21:11 UTC (rev 24678)
+++ trunk/src/lib/crypto/krb/deps 2011-03-05 13:31:02 UTC (rev 24679)
@@ -96,6 +96,19 @@
$(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
$(top_srcdir)/include/socket-utils.h combine_keys.c \
crypto_int.h
+crc32.so crc32.po $(OUTPRE)crc32.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../builtin/aes/aes.h \
+ $(srcdir)/../builtin/aes/uitypes.h $(srcdir)/../builtin/crypto_mod.h \
+ $(srcdir)/../builtin/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/krb5/preauth_plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ crc32.c crypto_int.h
crypto_length.so crypto_length.po $(OUTPRE)crypto_length.$(OBJEXT): \
$(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
$(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -382,6 +395,58 @@
$(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
$(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
crypto_int.h prf.c
+prf_cmac.so prf_cmac.po $(OUTPRE)prf_cmac.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(srcdir)/../builtin/aes/aes.h $(srcdir)/../builtin/aes/uitypes.h \
+ $(srcdir)/../builtin/crypto_mod.h $(srcdir)/../builtin/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/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h crypto_int.h prf_cmac.c
+prf_des.so prf_des.po $(OUTPRE)prf_des.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../builtin/aes/aes.h \
+ $(srcdir)/../builtin/aes/uitypes.h $(srcdir)/../builtin/crypto_mod.h \
+ $(srcdir)/../builtin/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/krb5/preauth_plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ crypto_int.h prf_des.c
+prf_dk.so prf_dk.po $(OUTPRE)prf_dk.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../builtin/aes/aes.h \
+ $(srcdir)/../builtin/aes/uitypes.h $(srcdir)/../builtin/crypto_mod.h \
+ $(srcdir)/../builtin/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/krb5/preauth_plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ crypto_int.h prf_dk.c
+prf_rc4.so prf_rc4.po $(OUTPRE)prf_rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../builtin/aes/aes.h \
+ $(srcdir)/../builtin/aes/uitypes.h $(srcdir)/../builtin/crypto_mod.h \
+ $(srcdir)/../builtin/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/krb5/preauth_plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ crypto_int.h prf_rc4.c
prng.so prng.po $(OUTPRE)prng.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../builtin/aes/aes.h \
Copied: trunk/src/lib/crypto/krb/derive.c (from rev 24677, trunk/src/lib/crypto/krb/dk/derive.c)
===================================================================
--- trunk/src/lib/crypto/krb/derive.c (rev 0)
+++ trunk/src/lib/crypto/krb/derive.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,299 @@
+/* -*- 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_key
+find_cached_dkey(struct derived_key *list, const krb5_data *constant)
+{
+ for (; list; list = list->next) {
+ if (data_eq(list->constant, *constant)) {
+ krb5_k_reference_key(NULL, list->dkey);
+ return list->dkey;
+ }
+ }
+ return NULL;
+}
+
+static krb5_error_code
+add_cached_dkey(krb5_key key, const krb5_data *constant,
+ const krb5_keyblock *dkeyblock, krb5_key *cached_dkey)
+{
+ krb5_key dkey;
+ krb5_error_code ret;
+ struct derived_key *dkent = NULL;
+ char *data = NULL;
+
+ /* Allocate fields for the new entry. */
+ dkent = malloc(sizeof(*dkent));
+ if (dkent == NULL)
+ goto cleanup;
+ data = malloc(constant->length);
+ if (data == NULL)
+ goto cleanup;
+ ret = krb5_k_create_key(NULL, dkeyblock, &dkey);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Add the new entry to the list. */
+ memcpy(data, constant->data, constant->length);
+ dkent->dkey = dkey;
+ dkent->constant.data = data;
+ dkent->constant.length = constant->length;
+ dkent->next = key->derived;
+ key->derived = dkent;
+
+ /* Return a "copy" of the cached key. */
+ krb5_k_reference_key(NULL, dkey);
+ *cached_dkey = dkey;
+ return 0;
+
+cleanup:
+ free(dkent);
+ free(data);
+ return ENOMEM;
+}
+
+static krb5_error_code
+derive_random_rfc3961(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *in_constant)
+{
+ size_t blocksize, keybytes, n;
+ krb5_error_code ret;
+ krb5_data block = empty_data();
+
+ blocksize = enc->block_size;
+ keybytes = enc->keybytes;
+
+ if (blocksize == 1)
+ return KRB5_BAD_ENCTYPE;
+ if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
+ return KRB5_CRYPTO_INTERNAL;
+
+ /* Allocate encryption data buffer. */
+ ret = alloc_data(&block, blocksize);
+ if (ret)
+ return ret;
+
+ /* Initialize the input block. */
+ if (in_constant->length == blocksize) {
+ memcpy(block.data, in_constant->data, blocksize);
+ } else {
+ krb5int_nfold(in_constant->length * 8,
+ (unsigned char *) in_constant->data,
+ blocksize * 8, (unsigned char *) block.data);
+ }
+
+ /* Loop encrypting the blocks until enough key bytes are generated. */
+ n = 0;
+ while (n < keybytes) {
+ ret = encrypt_block(enc, inkey, &block);
+ if (ret)
+ goto cleanup;
+
+ if ((keybytes - n) <= blocksize) {
+ memcpy(outrnd->data + n, block.data, (keybytes - n));
+ break;
+ }
+
+ memcpy(outrnd->data + n, block.data, blocksize);
+ n += blocksize;
+ }
+
+cleanup:
+ zapfree(block.data, blocksize);
+ return ret;
+}
+
+#ifdef CAMELLIA
+
+/*
+ * NIST SP800-108 KDF in feedback mode (section 5.2).
+ * Parameters:
+ * - CMAC (with enc as the enc provider) is the PRF.
+ * - A block counter of four bytes is used.
+ * - Label is the key derivation constant.
+ * - Context is empty.
+ * - Four bytes are used to encode the output length in the PRF input.
+ */
+static krb5_error_code
+derive_random_sp800_108_cmac(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *in_constant)
+{
+ size_t blocksize, keybytes, n;
+ krb5_crypto_iov iov[6];
+ krb5_error_code ret;
+ krb5_data prf;
+ unsigned int i;
+ unsigned char ibuf[4], Lbuf[4];
+
+ blocksize = enc->block_size;
+ keybytes = enc->keybytes;
+
+ if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
+ return KRB5_CRYPTO_INTERNAL;
+
+ /* Allocate encryption data buffer. */
+ ret = alloc_data(&prf, blocksize);
+ if (ret)
+ return ret;
+
+ /* K(i-1): the previous block of PRF output, initially all-zeros. */
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[0].data = prf;
+ /* [i]2: four-byte big-endian binary string giving the block counter */
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[1].data = make_data(ibuf, sizeof(ibuf));
+ /* Label: the fixed derived-key input */
+ iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[2].data = *in_constant;
+ /* 0x00: separator byte */
+ iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[3].data = make_data("", 1);
+ /* Context: (unused) */
+ iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[4].data = empty_data();
+ /* [L]2: four-byte big-endian binary string giving the output length */
+ iov[5].flags = KRB5_CRYPTO_TYPE_DATA;
+ iov[5].data = make_data(Lbuf, sizeof(Lbuf));
+ store_32_be(outrnd->length * 8, Lbuf);
+
+ for (i = 1, n = 0; n < keybytes; i++) {
+ /* Update the block counter. */
+ store_32_be(i, ibuf);
+
+ /* Compute a CMAC checksum, storing the result into K(i-1). */
+ ret = krb5int_cmac_checksum(enc, inkey, iov, 6, &prf);
+ if (ret)
+ goto cleanup;
+
+ /* Copy the result into the appropriate part of the output buffer. */
+ if (keybytes - n <= blocksize) {
+ memcpy(outrnd->data + n, prf.data, keybytes - n);
+ break;
+ }
+ memcpy(outrnd->data + n, prf.data, blocksize);
+ n += blocksize;
+ }
+
+cleanup:
+ zapfree(prf.data, blocksize);
+ return ret;
+}
+
+#endif /* CAMELLIA */
+
+krb5_error_code
+krb5int_derive_random(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_data *outrnd,
+ const krb5_data *in_constant, enum deriv_alg alg)
+{
+ switch (alg) {
+ case DERIVE_RFC3961:
+ return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
+#ifdef CAMELLIA
+ case DERIVE_SP800_108_CMAC:
+ return derive_random_sp800_108_cmac(enc, inkey, outrnd, in_constant);
+#endif
+ default:
+ return EINVAL;
+ }
+}
+
+/*
+ * Compute a derived key into the keyblock outkey. This variation on
+ * krb5int_derive_key does not cache the result, as it is only used
+ * directly in situations which are not expected to be repeated with
+ * the same inkey and constant.
+ */
+krb5_error_code
+krb5int_derive_keyblock(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_keyblock *outkey,
+ const krb5_data *in_constant, enum deriv_alg alg)
+{
+ krb5_error_code ret;
+ krb5_data rawkey = empty_data();
+
+ /* Allocate a buffer for the raw key bytes. */
+ ret = alloc_data(&rawkey, enc->keybytes);
+ if (ret)
+ goto cleanup;
+
+ /* Derive pseudo-random data for the key bytes. */
+ ret = krb5int_derive_random(enc, inkey, &rawkey, in_constant, alg);
+ if (ret)
+ goto cleanup;
+
+ /* Postprocess the key. */
+ ret = krb5_c_random_to_key(NULL, inkey->keyblock.enctype, &rawkey, outkey);
+
+cleanup:
+ zapfree(rawkey.data, enc->keybytes);
+ return ret;
+}
+
+krb5_error_code
+krb5int_derive_key(const struct krb5_enc_provider *enc,
+ krb5_key inkey, krb5_key *outkey,
+ const krb5_data *in_constant, enum deriv_alg alg)
+{
+ krb5_keyblock keyblock;
+ krb5_error_code ret;
+ krb5_key dkey;
+
+ *outkey = NULL;
+
+ /* Check for a cached result. */
+ dkey = find_cached_dkey(inkey->derived, in_constant);
+ if (dkey != NULL) {
+ *outkey = dkey;
+ return 0;
+ }
+
+ /* Derive into a temporary keyblock. */
+ keyblock.length = enc->keylength;
+ keyblock.contents = malloc(keyblock.length);
+ keyblock.enctype = inkey->keyblock.enctype;
+ if (keyblock.contents == NULL)
+ return ENOMEM;
+ ret = krb5int_derive_keyblock(enc, inkey, &keyblock, in_constant, alg);
+ if (ret)
+ goto cleanup;
+
+ /* Cache the derived key. */
+ ret = add_cached_dkey(inkey, in_constant, &keyblock, &dkey);
+ if (ret != 0)
+ goto cleanup;
+
+ *outkey = dkey;
+
+cleanup:
+ zapfree(keyblock.contents, keyblock.length);
+ return ret;
+}
Copied: trunk/src/lib/crypto/krb/enc_dk_cmac.c (from rev 24677, trunk/src/lib/crypto/krb/dk/dk_cmac.c)
===================================================================
--- trunk/src/lib/crypto/krb/enc_dk_cmac.c (rev 0)
+++ trunk/src/lib/crypto/krb/enc_dk_cmac.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,186 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/crypto/dk/dk_cmac.c - Derived-key enctype functions using CMAC */
+/*
+ * Copyright 2008, 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"
+
+#ifdef CAMELLIA
+
+#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
+
+/* AEAD */
+
+unsigned int
+krb5int_camellia_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type)
+{
+ switch (type) {
+ case KRB5_CRYPTO_TYPE_HEADER:
+ return ktp->enc->block_size;
+ case KRB5_CRYPTO_TYPE_PADDING:
+ return 0;
+ case KRB5_CRYPTO_TYPE_TRAILER:
+ case KRB5_CRYPTO_TYPE_CHECKSUM:
+ return ktp->enc->block_size;
+ default:
+ assert(0 && "bad type passed to krb5int_camellia_crypto_length");
+ return 0;
+ }
+}
+
+/* Derive encryption and integrity keys for CMAC-using enctypes. */
+static krb5_error_code
+derive_keys(const struct krb5_enc_provider *enc, krb5_key key,
+ krb5_keyusage usage, krb5_key *ke_out, krb5_key *ki_out)
+{
+ krb5_error_code ret;
+ unsigned char buf[K5CLENGTH];
+ krb5_data constant = make_data(buf, K5CLENGTH);
+ krb5_key ke, ki;
+
+ *ke_out = *ki_out = NULL;
+
+ /* Derive the encryption key. */
+ store_32_be(usage, buf);
+ buf[4] = 0xAA;
+ ret = krb5int_derive_key(enc, key, &ke, &constant, DERIVE_SP800_108_CMAC);
+ if (ret != 0)
+ return ret;
+
+ /* Derive the integrity key. */
+ buf[4] = 0x55;
+ ret = krb5int_derive_key(enc, key, &ki, &constant, DERIVE_SP800_108_CMAC);
+ if (ret != 0) {
+ krb5_k_free_key(NULL, ke);
+ return ret;
+ }
+
+ *ke_out = ke;
+ *ki_out = ki;
+ return 0;
+}
+
+krb5_error_code
+krb5int_dk_cmac_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ krb5_error_code ret;
+ krb5_crypto_iov *header, *trailer, *padding;
+ krb5_data cksum = empty_data();
+ krb5_key ke = NULL, ki = NULL;
+
+ /* E(Confounder | Plaintext | Pad) | Checksum */
+
+ /* Validate header and trailer lengths, and zero out padding length. */
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL || header->data.length < enc->block_size)
+ return KRB5_BAD_MSIZE;
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer == NULL || trailer->data.length < enc->block_size)
+ return KRB5_BAD_MSIZE;
+ padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
+ if (padding != NULL)
+ padding->data.length = 0;
+
+ /* Derive the encryption and integrity keys. */
+ ret = derive_keys(enc, key, usage, &ke, &ki);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Generate confounder. */
+ header->data.length = enc->block_size;
+ ret = krb5_c_random_make_octets(NULL, &header->data);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Checksum the plaintext. */
+ ret = krb5int_cmac_checksum(enc, ki, data, num_data, &trailer->data);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Encrypt the plaintext (header | data | padding) */
+ ret = enc->encrypt(ke, ivec, data, num_data);
+ if (ret != 0)
+ goto cleanup;
+
+cleanup:
+ krb5_k_free_key(NULL, ke);
+ krb5_k_free_key(NULL, ki);
+ zapfree(cksum.data, cksum.length);
+ return ret;
+}
+
+krb5_error_code
+krb5int_dk_cmac_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ krb5_error_code ret;
+ krb5_crypto_iov *header, *trailer;
+ krb5_data cksum;
+ krb5_key ke = NULL, ki = NULL;
+
+ /* E(Confounder | Plaintext | Pad) | Checksum */
+
+ /* Validate header and trailer lengths. */
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL || header->data.length != enc->block_size)
+ return KRB5_BAD_MSIZE;
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer == NULL || trailer->data.length != enc->block_size)
+ return KRB5_BAD_MSIZE;
+
+ /* Derive the encryption and integrity keys. */
+ ret = derive_keys(enc, key, usage, &ke, &ki);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Decrypt the plaintext (header | data | padding). */
+ ret = enc->decrypt(ke, ivec, data, num_data);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Verify the hash. */
+ ret = alloc_data(&cksum, enc->block_size);
+ if (ret != 0)
+ goto cleanup;
+ ret = krb5int_cmac_checksum(enc, ki, data, num_data, &cksum);
+ if (ret != 0)
+ goto cleanup;
+ if (!data_eq(cksum, trailer->data))
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+
+cleanup:
+ krb5_k_free_key(NULL, ke);
+ krb5_k_free_key(NULL, ki);
+ zapfree(cksum.data, cksum.length);
+ return ret;
+}
+
+#endif /* CAMELLIA */
Copied: trunk/src/lib/crypto/krb/enc_dk_hmac.c (from rev 24677, trunk/src/lib/crypto/krb/dk/dk_aead.c)
===================================================================
--- trunk/src/lib/crypto/krb/enc_dk_hmac.c (rev 0)
+++ trunk/src/lib/crypto/krb/enc_dk_hmac.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,270 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/dk/dk_aead.c
+ *
+ * Copyright 2008, 2009 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"
+
+#define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */
+
+/* AEAD */
+
+unsigned int
+krb5int_dk_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type)
+{
+ switch (type) {
+ case KRB5_CRYPTO_TYPE_HEADER:
+ case KRB5_CRYPTO_TYPE_PADDING:
+ return ktp->enc->block_size;
+ case KRB5_CRYPTO_TYPE_TRAILER:
+ case KRB5_CRYPTO_TYPE_CHECKSUM:
+ return ktp->hash->hashsize;
+ default:
+ assert(0 && "invalid cryptotype passed to krb5int_dk_crypto_length");
+ return 0;
+ }
+}
+
+unsigned int
+krb5int_aes_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type)
+{
+ switch (type) {
+ case KRB5_CRYPTO_TYPE_HEADER:
+ return ktp->enc->block_size;
+ case KRB5_CRYPTO_TYPE_PADDING:
+ return 0;
+ case KRB5_CRYPTO_TYPE_TRAILER:
+ case KRB5_CRYPTO_TYPE_CHECKSUM:
+ return 96 / 8;
+ default:
+ assert(0 && "invalid cryptotype passed to krb5int_aes_crypto_length");
+ return 0;
+ }
+}
+
+krb5_error_code
+krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
+ krb5_error_code ret;
+ unsigned char constantdata[K5CLENGTH];
+ krb5_data d1, d2;
+ krb5_crypto_iov *header, *trailer, *padding;
+ krb5_key ke = NULL, ki = NULL;
+ size_t i;
+ unsigned int blocksize, hmacsize, plainlen = 0, padsize = 0;
+ unsigned char *cksum = NULL;
+
+ /* E(Confounder | Plaintext | Pad) | Checksum */
+
+ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING);
+ hmacsize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
+
+ for (i = 0; i < num_data; i++) {
+ krb5_crypto_iov *iov = &data[i];
+
+ if (iov->flags == KRB5_CRYPTO_TYPE_DATA)
+ plainlen += iov->data.length;
+ }
+
+ /* Validate header and trailer lengths. */
+
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL || header->data.length < enc->block_size)
+ return KRB5_BAD_MSIZE;
+
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer == NULL || trailer->data.length < hmacsize)
+ return KRB5_BAD_MSIZE;
+
+ if (blocksize != 0) {
+ /* Check that the input data is correctly padded. */
+ if (plainlen % blocksize)
+ padsize = blocksize - (plainlen % blocksize);
+ }
+
+ padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
+ if (padsize && (padding == NULL || padding->data.length < padsize))
+ return KRB5_BAD_MSIZE;
+
+ if (padding != NULL) {
+ memset(padding->data.data, 0, padsize);
+ padding->data.length = padsize;
+ }
+
+ cksum = k5alloc(hash->hashsize, &ret);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive the keys. */
+
+ d1.data = (char *)constantdata;
+ d1.length = K5CLENGTH;
+
+ store_32_be(usage, constantdata);
+
+ d1.data[4] = 0xAA;
+
+ ret = krb5int_derive_key(enc, key, &ke, &d1, DERIVE_RFC3961);
+ if (ret != 0)
+ goto cleanup;
+
+ d1.data[4] = 0x55;
+
+ ret = krb5int_derive_key(enc, key, &ki, &d1, DERIVE_RFC3961);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Generate confounder. */
+
+ header->data.length = enc->block_size;
+
+ ret = krb5_c_random_make_octets(/* XXX */ NULL, &header->data);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Hash the plaintext. */
+ d2.length = hash->hashsize;
+ d2.data = (char *)cksum;
+
+ ret = krb5int_hmac(hash, ki, data, num_data, &d2);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Encrypt the plaintext (header | data | padding) */
+ ret = enc->encrypt(ke, ivec, data, num_data);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Possibly truncate the hash */
+ assert(hmacsize <= d2.length);
+
+ memcpy(trailer->data.data, cksum, hmacsize);
+ trailer->data.length = hmacsize;
+
+cleanup:
+ krb5_k_free_key(NULL, ke);
+ krb5_k_free_key(NULL, ki);
+ free(cksum);
+ return ret;
+}
+
+krb5_error_code
+krb5int_dk_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
+ krb5_error_code ret;
+ unsigned char constantdata[K5CLENGTH];
+ krb5_data d1;
+ krb5_crypto_iov *header, *trailer;
+ krb5_key ke = NULL, ki = NULL;
+ size_t i;
+ unsigned int blocksize; /* enc block size, not confounder len */
+ unsigned int hmacsize, cipherlen = 0;
+ unsigned char *cksum = NULL;
+
+ /* E(Confounder | Plaintext | Pad) | Checksum */
+
+ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING);
+ hmacsize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER);
+
+ if (blocksize != 0) {
+ /* Check that the input data is correctly padded. */
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (ENCRYPT_DATA_IOV(iov))
+ cipherlen += iov->data.length;
+ }
+ if (cipherlen % blocksize != 0)
+ return KRB5_BAD_MSIZE;
+ }
+
+ /* Validate header and trailer lengths */
+
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL || header->data.length != enc->block_size)
+ return KRB5_BAD_MSIZE;
+
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer == NULL || trailer->data.length != hmacsize)
+ return KRB5_BAD_MSIZE;
+
+ cksum = k5alloc(hash->hashsize, &ret);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive the keys. */
+
+ d1.data = (char *)constantdata;
+ d1.length = K5CLENGTH;
+
+ store_32_be(usage, constantdata);
+
+ d1.data[4] = 0xAA;
+
+ ret = krb5int_derive_key(enc, key, &ke, &d1, DERIVE_RFC3961);
+ if (ret != 0)
+ goto cleanup;
+
+ d1.data[4] = 0x55;
+
+ ret = krb5int_derive_key(enc, key, &ki, &d1, DERIVE_RFC3961);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Decrypt the plaintext (header | data | padding). */
+ ret = enc->decrypt(ke, ivec, data, num_data);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Verify the hash. */
+ d1.length = hash->hashsize; /* non-truncated length */
+ d1.data = (char *)cksum;
+
+ ret = krb5int_hmac(hash, ki, data, num_data, &d1);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Compare only the possibly truncated length. */
+ if (memcmp(cksum, trailer->data.data, hmacsize) != 0) {
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ goto cleanup;
+ }
+
+cleanup:
+ krb5_k_free_key(NULL, ke);
+ krb5_k_free_key(NULL, ki);
+ free(cksum);
+ return ret;
+}
Copied: trunk/src/lib/crypto/krb/enc_old.c (from rev 24677, trunk/src/lib/crypto/krb/old/old_aead.c)
===================================================================
--- trunk/src/lib/crypto/krb/enc_old.c (rev 0)
+++ trunk/src/lib/crypto/krb/enc_old.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,189 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/old/old_aead.c
+ *
+ * Copyright 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"
+
+unsigned int
+krb5int_old_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type)
+{
+ switch (type) {
+ case KRB5_CRYPTO_TYPE_HEADER:
+ return ktp->enc->block_size + ktp->hash->hashsize;
+ case KRB5_CRYPTO_TYPE_PADDING:
+ return ktp->enc->block_size;
+ case KRB5_CRYPTO_TYPE_TRAILER:
+ return 0;
+ case KRB5_CRYPTO_TYPE_CHECKSUM:
+ return ktp->hash->hashsize;
+ default:
+ assert(0 && "invalid cryptotype passed to krb5int_old_crypto_length");
+ return 0;
+ }
+}
+
+krb5_error_code
+krb5int_old_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
+ krb5_error_code ret;
+ krb5_crypto_iov *header, *trailer, *padding;
+ krb5_data checksum, confounder, crcivec = empty_data();
+ unsigned int plainlen, padsize;
+ size_t i;
+
+ /* E(Confounder | Checksum | Plaintext | Pad) */
+
+ plainlen = enc->block_size + hash->hashsize;
+ for (i = 0; i < num_data; i++) {
+ krb5_crypto_iov *iov = &data[i];
+
+ if (iov->flags == KRB5_CRYPTO_TYPE_DATA)
+ plainlen += iov->data.length;
+ }
+
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL ||
+ header->data.length < enc->block_size + hash->hashsize)
+ return KRB5_BAD_MSIZE;
+
+ /* Trailer may be absent. */
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer != NULL)
+ trailer->data.length = 0;
+
+ /* Check that the input data is correctly padded. */
+ padsize = krb5_roundup(plainlen, enc->block_size) - plainlen;
+ padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
+ if (padsize > 0 && (padding == NULL || padding->data.length < padsize))
+ return KRB5_BAD_MSIZE;
+ if (padding) {
+ padding->data.length = padsize;
+ memset(padding->data.data, 0, padsize);
+ }
+
+ /* Generate a confounder in the header block. */
+ confounder = make_data(header->data.data, enc->block_size);
+ ret = krb5_c_random_make_octets(0, &confounder);
+ if (ret != 0)
+ goto cleanup;
+ checksum = make_data(header->data.data + enc->block_size, hash->hashsize);
+ memset(checksum.data, 0, hash->hashsize);
+
+ /* Checksum the plaintext with zeroed checksum and padding. */
+ ret = hash->hash(data, num_data, &checksum);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Use the key as the ivec for des-cbc-crc if none was provided. */
+ if (key->keyblock.enctype == ENCTYPE_DES_CBC_CRC && ivec == NULL) {
+ ret = alloc_data(&crcivec, key->keyblock.length);
+ memcpy(crcivec.data, key->keyblock.contents, key->keyblock.length);
+ ivec = &crcivec;
+ }
+
+ ret = enc->encrypt(key, ivec, data, num_data);
+ if (ret != 0)
+ goto cleanup;
+
+cleanup:
+ zapfree(crcivec.data, crcivec.length);
+ return ret;
+}
+
+krb5_error_code
+krb5int_old_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
+ krb5_error_code ret;
+ krb5_crypto_iov *header, *trailer;
+ krb5_data checksum, crcivec = empty_data();
+ char *saved_checksum = NULL;
+ size_t i;
+ unsigned int cipherlen = 0;
+
+ /* Check that the input data is correctly padded. */
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (ENCRYPT_IOV(iov))
+ cipherlen += iov->data.length;
+ }
+ if (cipherlen % enc->block_size != 0)
+ return KRB5_BAD_MSIZE;
+
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL ||
+ header->data.length != enc->block_size + hash->hashsize)
+ return KRB5_BAD_MSIZE;
+
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer != NULL && trailer->data.length != 0)
+ return KRB5_BAD_MSIZE;
+
+ /* Use the key as the ivec for des-cbc-crc if none was provided. */
+ if (key->keyblock.enctype == ENCTYPE_DES_CBC_CRC && ivec == NULL) {
+ ret = alloc_data(&crcivec, key->keyblock.length);
+ memcpy(crcivec.data, key->keyblock.contents, key->keyblock.length);
+ ivec = &crcivec;
+ }
+
+ /* Decrypt the ciphertext. */
+ ret = enc->decrypt(key, ivec, data, num_data);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Save the checksum, then zero it out in the plaintext. */
+ checksum = make_data(header->data.data + enc->block_size, hash->hashsize);
+ saved_checksum = k5alloc(hash->hashsize, &ret);
+ if (saved_checksum == NULL)
+ goto cleanup;
+ memcpy(saved_checksum, checksum.data, checksum.length);
+ memset(checksum.data, 0, checksum.length);
+
+ /*
+ * Checksum the plaintext (with zeroed checksum field), storing the result
+ * back into the plaintext field we just zeroed out. Then compare it to
+ * the saved checksum.
+ */
+ ret = hash->hash(data, num_data, &checksum);
+ if (memcmp(checksum.data, saved_checksum, checksum.length) != 0) {
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ goto cleanup;
+ }
+
+cleanup:
+ zapfree(crcivec.data, crcivec.length);
+ zapfree(saved_checksum, hash->hashsize);
+ return ret;
+}
Copied: trunk/src/lib/crypto/krb/enc_raw.c (from rev 24677, trunk/src/lib/crypto/krb/raw/raw_aead.c)
===================================================================
--- trunk/src/lib/crypto/krb/enc_raw.c (rev 0)
+++ trunk/src/lib/crypto/krb/enc_raw.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,110 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/raw/raw_aead.c
+ *
+ * Copyright 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"
+
+unsigned int
+krb5int_raw_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type)
+{
+ switch (type) {
+ case KRB5_CRYPTO_TYPE_PADDING:
+ return ktp->enc->block_size;
+ default:
+ return 0;
+ }
+}
+
+krb5_error_code
+krb5int_raw_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ krb5_crypto_iov *padding;
+ size_t i;
+ unsigned int blocksize, plainlen = 0, padsize = 0;
+
+ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING);
+
+ for (i = 0; i < num_data; i++) {
+ krb5_crypto_iov *iov = &data[i];
+
+ if (iov->flags == KRB5_CRYPTO_TYPE_DATA)
+ plainlen += iov->data.length;
+ }
+
+ if (blocksize != 0) {
+ /* Check that the input data is correctly padded */
+ if (plainlen % blocksize)
+ padsize = blocksize - (plainlen % blocksize);
+ }
+
+ padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
+ if (padsize && (padding == NULL || padding->data.length < padsize))
+ return KRB5_BAD_MSIZE;
+
+ if (padding != NULL) {
+ memset(padding->data.data, 0, padsize);
+ padding->data.length = padsize;
+ }
+
+ return ktp->enc->encrypt(key, ivec, data, num_data);
+}
+
+krb5_error_code
+krb5int_raw_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ size_t i;
+ unsigned int blocksize = 0; /* enc block size, not confounder len */
+ unsigned int cipherlen = 0;
+
+ /* E(Confounder | Plaintext | Pad) | Checksum */
+
+ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING);
+
+ for (i = 0; i < num_data; i++) {
+ const krb5_crypto_iov *iov = &data[i];
+
+ if (ENCRYPT_DATA_IOV(iov))
+ cipherlen += iov->data.length;
+ }
+
+ if (blocksize == 0) {
+ /* Check for correct input length in CTS mode */
+ if (ktp->enc->block_size != 0 && cipherlen < ktp->enc->block_size)
+ return KRB5_BAD_MSIZE;
+ } else {
+ /* Check that the input data is correctly padded */
+ if (cipherlen % blocksize != 0)
+ return KRB5_BAD_MSIZE;
+ }
+
+ return ktp->enc->decrypt(key, ivec, data, num_data);
+}
Copied: trunk/src/lib/crypto/krb/enc_rc4.c (from rev 24677, trunk/src/lib/crypto/krb/arcfour/arcfour.c)
===================================================================
--- trunk/src/lib/crypto/krb/enc_rc4.c (rev 0)
+++ trunk/src/lib/crypto/krb/enc_rc4.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,347 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+
+ ARCFOUR cipher (based on a cipher posted on the Usenet in Spring-95).
+ This cipher is widely believed and has been tested to be equivalent
+ with the RC4 cipher from RSA Data Security, Inc. (RC4 is a trademark
+ of RSA Data Security)
+
+*/
+#include "crypto_int.h"
+
+#define CONFOUNDERLENGTH 8
+
+const char l40[] = "fortybits";
+
+krb5_keyusage
+krb5int_arcfour_translate_usage(krb5_keyusage usage)
+{
+ switch (usage) {
+ case 1: return 1; /* AS-REQ PA-ENC-TIMESTAMP padata timestamp, */
+ case 2: return 2; /* ticket from kdc */
+ case 3: return 8; /* as-rep encrypted part */
+ case 4: return 4; /* tgs-req authz data */
+ case 5: return 5; /* tgs-req authz data in subkey */
+ case 6: return 6; /* tgs-req authenticator cksum */
+ case 7: return 7; /* tgs-req authenticator */
+ case 8: return 8;
+ case 9: return 9; /* tgs-rep encrypted with subkey */
+ case 10: return 10; /* ap-rep authentication cksum (never used by MS) */
+ case 11: return 11; /* app-req authenticator */
+ case 12: return 12; /* app-rep encrypted part */
+ case 23: return 13; /* sign wrap token*/
+ default: return usage;
+ }
+}
+
+/* Derive a usage key from a session key and krb5 usage constant. */
+static krb5_error_code
+usage_key(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *session_keyblock, krb5_keyusage usage,
+ krb5_keyblock *out)
+{
+ char salt_buf[14];
+ unsigned int salt_len;
+ krb5_data out_data = make_data(out->contents, out->length);
+ krb5_crypto_iov iov;
+ krb5_keyusage ms_usage;
+
+ /* Generate the salt. */
+ ms_usage = krb5int_arcfour_translate_usage(usage);
+ if (session_keyblock->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
+ memcpy(salt_buf, l40, 10);
+ store_32_le(ms_usage, salt_buf + 10);
+ salt_len = 14;
+ } else {
+ store_32_le(ms_usage, salt_buf);
+ salt_len = 4;
+ }
+
+ /* Compute HMAC(key, salt) to produce the usage key. */
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = make_data(salt_buf, salt_len);
+ return krb5int_hmac_keyblock(hash, session_keyblock, &iov, 1, &out_data);
+}
+
+/* Derive an encryption key from a usage key and (typically) checksum. */
+static krb5_error_code
+enc_key(const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *usage_keyblock, const krb5_data *checksum,
+ krb5_keyblock *out)
+{
+ krb5_keyblock *trunc_keyblock = NULL;
+ krb5_data out_data = make_data(out->contents, out->length);
+ krb5_crypto_iov iov;
+ krb5_error_code ret;
+
+ /* Copy usage_keyblock to trunc_keyblock and truncate if exportable. */
+ ret = krb5int_c_copy_keyblock(NULL, usage_keyblock, &trunc_keyblock);
+ if (ret != 0)
+ return ret;
+ if (trunc_keyblock->enctype == ENCTYPE_ARCFOUR_HMAC_EXP)
+ memset(trunc_keyblock->contents + 7, 0xab, 9);
+
+ /* Compute HMAC(trunc_key, checksum) to produce the encryption key. */
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *checksum;
+ ret = krb5int_hmac_keyblock(hash, trunc_keyblock, &iov, 1, &out_data);
+ krb5int_c_free_keyblock(NULL, trunc_keyblock);
+ return ret;
+}
+
+unsigned int
+krb5int_arcfour_crypto_length(const struct krb5_keytypes *ktp,
+ krb5_cryptotype type)
+{
+ switch (type) {
+ case KRB5_CRYPTO_TYPE_HEADER:
+ return ktp->hash->hashsize + CONFOUNDERLENGTH;
+ case KRB5_CRYPTO_TYPE_PADDING:
+ case KRB5_CRYPTO_TYPE_TRAILER:
+ return 0;
+ case KRB5_CRYPTO_TYPE_CHECKSUM:
+ return ktp->hash->hashsize;
+ default:
+ assert(0 &&
+ "invalid cryptotype passed to krb5int_arcfour_crypto_length");
+ return 0;
+ }
+}
+
+/* Encrypt or decrypt using a keyblock. */
+static krb5_error_code
+keyblock_crypt(const struct krb5_enc_provider *enc, krb5_keyblock *keyblock,
+ const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data)
+{
+ krb5_error_code ret;
+ krb5_key key;
+
+ ret = krb5_k_create_key(NULL, keyblock, &key);
+ if (ret != 0)
+ return ret;
+ /* Works for encryption or decryption since arcfour is a stream cipher. */
+ ret = enc->encrypt(key, ivec, data, num_data);
+ krb5_k_free_key(NULL, key);
+ return ret;
+}
+
+krb5_error_code
+krb5int_arcfour_encrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
+ krb5_error_code ret;
+ krb5_crypto_iov *header, *trailer;
+ krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
+ krb5_data checksum, confounder, header_data;
+ size_t i;
+
+ /*
+ * Caller must have provided space for the header, padding
+ * and trailer; per RFC 4757 we will arrange it as:
+ *
+ * Checksum | E(Confounder | Plaintext)
+ */
+
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL ||
+ header->data.length < hash->hashsize + CONFOUNDERLENGTH)
+ return KRB5_BAD_MSIZE;
+
+ header_data = header->data;
+
+ /* Trailer may be absent. */
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer != NULL)
+ trailer->data.length = 0;
+
+ /* Ensure that there is no padding. */
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags == KRB5_CRYPTO_TYPE_PADDING)
+ data[i].data.length = 0;
+ }
+
+ ret = krb5int_c_init_keyblock(NULL, key->keyblock.enctype, enc->keybytes,
+ &usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+ ret = krb5int_c_init_keyblock(NULL, key->keyblock.enctype, enc->keybytes,
+ &enc_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive a usage key from the session key and usage. */
+ ret = usage_key(enc, hash, &key->keyblock, usage, usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Generate a confounder in the header block, after the checksum. */
+ header->data.length = hash->hashsize + CONFOUNDERLENGTH;
+ confounder = make_data(header->data.data + hash->hashsize,
+ CONFOUNDERLENGTH);
+ ret = krb5_c_random_make_octets(0, &confounder);
+ if (ret != 0)
+ goto cleanup;
+ checksum = make_data(header->data.data, hash->hashsize);
+
+ /* Adjust pointers so confounder is at start of header. */
+ header->data.length -= hash->hashsize;
+ header->data.data += hash->hashsize;
+
+ /* Compute the checksum using the usage key. */
+ ret = krb5int_hmac_keyblock(hash, usage_keyblock, data, num_data,
+ &checksum);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive the encryption key from the usage key and checksum. */
+ ret = enc_key(enc, hash, usage_keyblock, &checksum, enc_keyblock);
+ if (ret)
+ goto cleanup;
+
+ ret = keyblock_crypt(enc, enc_keyblock, ivec, data, num_data);
+
+cleanup:
+ header->data = header_data; /* Restore header pointers. */
+ krb5int_c_free_keyblock(NULL, usage_keyblock);
+ krb5int_c_free_keyblock(NULL, enc_keyblock);
+ return ret;
+}
+
+krb5_error_code
+krb5int_arcfour_decrypt(const struct krb5_keytypes *ktp, krb5_key key,
+ krb5_keyusage usage, const krb5_data *ivec,
+ krb5_crypto_iov *data, size_t num_data)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
+ krb5_error_code ret;
+ krb5_crypto_iov *header, *trailer;
+ krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
+ krb5_data checksum, header_data, comp_checksum = empty_data();
+
+ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
+ if (header == NULL ||
+ header->data.length != hash->hashsize + CONFOUNDERLENGTH)
+ return KRB5_BAD_MSIZE;
+
+ header_data = header->data;
+
+ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
+ if (trailer != NULL && trailer->data.length != 0)
+ return KRB5_BAD_MSIZE;
+
+ /* Allocate buffers. */
+ ret = alloc_data(&comp_checksum, hash->hashsize);
+ if (ret != 0)
+ goto cleanup;
+ ret = krb5int_c_init_keyblock(NULL, key->keyblock.enctype, enc->keybytes,
+ &usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+ ret = krb5int_c_init_keyblock(NULL, key->keyblock.enctype, enc->keybytes,
+ &enc_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ checksum = make_data(header->data.data, hash->hashsize);
+
+ /* Adjust pointers so confounder is at start of header. */
+ header->data.length -= hash->hashsize;
+ header->data.data += hash->hashsize;
+
+ /* We may have to try two usage values; see below. */
+ do {
+ /* Derive a usage key from the session key and usage. */
+ ret = usage_key(enc, hash, &key->keyblock, usage, usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive the encryption key from the usage key and checksum. */
+ ret = enc_key(enc, hash, usage_keyblock, &checksum, enc_keyblock);
+ if (ret)
+ goto cleanup;
+
+ /* Decrypt the ciphertext. */
+ ret = keyblock_crypt(enc, enc_keyblock, ivec, data, num_data);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Compute HMAC(usage key, plaintext) to get the checksum. */
+ ret = krb5int_hmac_keyblock(hash, usage_keyblock, data, num_data,
+ &comp_checksum);
+ if (ret != 0)
+ goto cleanup;
+
+ if (memcmp(checksum.data, comp_checksum.data, hash->hashsize) != 0) {
+ if (usage == 9) {
+ /*
+ * RFC 4757 specifies usage 8 for TGS-REP encrypted parts
+ * encrypted in a subkey, but the value used by MS is actually
+ * 9. We now use 9 to start with, but fall back to 8 on
+ * failure in case we are communicating with a KDC using the
+ * value from the RFC. ivec is always NULL in this case.
+ * We need to re-encrypt the data in the wrong key first.
+ */
+ ret = keyblock_crypt(enc, enc_keyblock, NULL, data, num_data);
+ if (ret != 0)
+ goto cleanup;
+ usage = 8;
+ continue;
+ }
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ goto cleanup;
+ }
+
+ break;
+ } while (1);
+
+cleanup:
+ header->data = header_data; /* Restore header pointers. */
+ krb5int_c_free_keyblock(NULL, usage_keyblock);
+ krb5int_c_free_keyblock(NULL, enc_keyblock);
+ zapfree(comp_checksum.data, comp_checksum.length);
+ return ret;
+}
+
+krb5_error_code
+krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage,
+ const krb5_data *kd_data, krb5_crypto_iov *data,
+ size_t num_data)
+{
+ const struct krb5_enc_provider *enc = &krb5int_enc_arcfour;
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
+ krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL;
+ krb5_error_code ret;
+
+ ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+ &usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+ ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes,
+ &enc_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive a usage key from the session key and usage. */
+ ret = usage_key(enc, hash, keyblock, usage, usage_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive the encryption key from the usage key and kd_data. */
+ ret = enc_key(enc, hash, usage_keyblock, kd_data, enc_keyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Encrypt or decrypt (encrypt_iov works for both) the input. */
+ ret = keyblock_crypt(enc, enc_keyblock, 0, data, num_data);
+
+cleanup:
+ krb5int_c_free_keyblock(NULL, usage_keyblock);
+ krb5int_c_free_keyblock(NULL, enc_keyblock);
+ return ret;
+}
Copied: trunk/src/lib/crypto/krb/prf_cmac.c (from rev 24677, trunk/src/lib/crypto/krb/prf/cmac_prf.c)
===================================================================
--- trunk/src/lib/crypto/krb/prf_cmac.c (rev 0)
+++ trunk/src/lib/crypto/krb/prf_cmac.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,68 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/prf/cmac_prf.c
+ *
+ * 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.
+ *
+ *
+ *
+ * This file contains an implementation of the RFC 3961 PRF for
+ *simplified profile enctypes.
+ */
+
+#include "crypto_int.h"
+
+#ifdef CAMELLIA
+
+krb5_error_code
+krb5int_dk_cmac_prf(const struct krb5_keytypes *ktp, krb5_key key,
+ const krb5_data *in, krb5_data *out)
+{
+ krb5_crypto_iov iov;
+ krb5_data prfconst = make_data("prf", 3);
+ krb5_key kp = NULL;
+ krb5_error_code ret;
+
+ if (ktp->prf_length != ktp->enc->block_size)
+ return KRB5_BAD_MSIZE;
+
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *in;
+
+ /* Derive a key using the PRF constant. */
+ ret = krb5int_derive_key(ktp->enc, key, &kp, &prfconst,
+ DERIVE_SP800_108_CMAC);
+ if (ret != 0)
+ goto cleanup;
+
+ /* PRF is CMAC of input */
+ ret = krb5int_cmac_checksum(ktp->enc, kp, &iov, 1, out);
+ if (ret != 0)
+ goto cleanup;
+
+cleanup:
+ krb5_k_free_key(NULL, kp);
+ return ret;
+}
+
+#endif /* CAMELLIA */
Copied: trunk/src/lib/crypto/krb/prf_des.c (from rev 24677, trunk/src/lib/crypto/krb/prf/des_prf.c)
===================================================================
--- trunk/src/lib/crypto/krb/prf_des.c (rev 0)
+++ trunk/src/lib/crypto/krb/prf_des.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,53 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/prf//des_prf.c
+ *
+ * Copyright (C) 2004, 2009 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 file contains an implementation of the RFC 3961 PRF for
+ * des-cbc-crc, des-cbc-md4, and des-cbc-md5 enctypes.
+ */
+
+#include "crypto_int.h"
+
+krb5_error_code
+krb5int_des_prf(const struct krb5_keytypes *ktp, krb5_key key,
+ const krb5_data *in, krb5_data *out)
+{
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
+ krb5_crypto_iov iov;
+ krb5_error_code ret;
+
+ /* Compute a hash of the input, storing into the output buffer. */
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *in;
+ ret = hash->hash(&iov, 1, out);
+ if (ret != 0)
+ return ret;
+
+ /* Encrypt the hash in place. */
+ iov.data = *out;
+ return ktp->enc->encrypt(key, NULL, &iov, 1);
+}
Copied: trunk/src/lib/crypto/krb/prf_dk.c (from rev 24677, trunk/src/lib/crypto/krb/prf/dk_prf.c)
===================================================================
--- trunk/src/lib/crypto/krb/prf_dk.c (rev 0)
+++ trunk/src/lib/crypto/krb/prf_dk.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,75 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/prf/dk_prf.c
+ *
+ * Copyright (C) 2004 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 file contains an implementation of the RFC 3961 PRF for
+ *simplified profile enctypes.
+ */
+
+#include "crypto_int.h"
+
+krb5_error_code
+krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key,
+ const krb5_data *in, krb5_data *out)
+{
+ const struct krb5_enc_provider *enc = ktp->enc;
+ const struct krb5_hash_provider *hash = ktp->hash;
+ krb5_crypto_iov iov;
+ krb5_data cksum = empty_data(), prfconst = make_data("prf", 3);
+ krb5_key kp = NULL;
+ krb5_error_code ret;
+
+ /* Hash the input data into an allocated buffer. */
+ ret = alloc_data(&cksum, hash->hashsize);
+ if (ret != 0)
+ goto cleanup;
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *in;
+ ret = hash->hash(&iov, 1, &cksum);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Derive a key using the PRF constant. */
+ ret = krb5int_derive_key(ktp->enc, key, &kp, &prfconst, DERIVE_RFC3961);
+ if (ret != 0)
+ goto cleanup;
+
+ /* Truncate the hash to the closest multiple of the block size. */
+ iov.data.data = cksum.data;
+ iov.data.length = (hash->hashsize / enc->block_size) * enc->block_size;
+
+ /* Encrypt the truncated hash in the derived key to get the output. */
+ ret = ktp->enc->encrypt(kp, NULL, &iov, 1);
+ if (ret != 0)
+ goto cleanup;
+ memcpy(out->data, iov.data.data, out->length);
+
+cleanup:
+ zapfree(cksum.data, hash->hashsize);
+ krb5_k_free_key(NULL, kp);
+ return ret;
+}
Copied: trunk/src/lib/crypto/krb/prf_rc4.c (from rev 24677, trunk/src/lib/crypto/krb/prf/rc4_prf.c)
===================================================================
--- trunk/src/lib/crypto/krb/prf_rc4.c (rev 0)
+++ trunk/src/lib/crypto/krb/prf_rc4.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,41 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/crypto/krb/prf/rc4_prf.c
+ *
+ * Copyright (C) 2009 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"
+
+krb5_error_code
+krb5int_arcfour_prf(const struct krb5_keytypes *ktp, krb5_key key,
+ const krb5_data *in, krb5_data *out)
+{
+ krb5_crypto_iov iov;
+
+ assert(out->length == 20);
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = *in;
+ return krb5int_hmac(&krb5int_hash_sha1, key, &iov, 1, out);
+}
Copied: trunk/src/lib/crypto/krb/s2k_des.c (from rev 24677, trunk/src/lib/crypto/krb/old/des_stringtokey.c)
===================================================================
--- trunk/src/lib/crypto/krb/s2k_des.c (rev 0)
+++ trunk/src/lib/crypto/krb/s2k_des.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,50 @@
+/* -*- 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"
+
+krb5_error_code
+krb5int_des_string_to_key(const struct krb5_keytypes *ktp,
+ const krb5_data *string, const krb5_data *salt,
+ const krb5_data *parm, krb5_keyblock *key)
+{
+ int type;
+ if (parm) {
+ if (parm->length != 1)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+ type = parm->data[0];
+ }
+ else type = 0;
+ switch(type) {
+ case 0:
+ return(mit_des_string_to_key_int(key, string, salt));
+ case 1:
+ return mit_afs_string_to_key(key, string, salt);
+ default:
+ return KRB5_ERR_BAD_S2K_PARAMS;
+ }
+}
Copied: trunk/src/lib/crypto/krb/s2k_pbkdf2.c (from rev 24677, trunk/src/lib/crypto/krb/dk/stringtokey.c)
===================================================================
--- trunk/src/lib/crypto/krb/s2k_pbkdf2.c (rev 0)
+++ trunk/src/lib/crypto/krb/s2k_pbkdf2.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,199 @@
+/* -*- 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 const unsigned char kerberos[] = "kerberos";
+#define kerberos_len (sizeof(kerberos)-1)
+
+krb5_error_code
+krb5int_dk_string_to_key(const struct krb5_keytypes *ktp,
+ const krb5_data *string, const krb5_data *salt,
+ const krb5_data *parms, krb5_keyblock *keyblock)
+{
+ krb5_error_code ret;
+ size_t keybytes, keylength, concatlen;
+ unsigned char *concat = NULL, *foldstring = NULL, *foldkeydata = NULL;
+ krb5_data indata;
+ krb5_keyblock foldkeyblock;
+ krb5_key foldkey = NULL;
+
+ /* keyblock->length is checked by krb5int_derive_key. */
+
+ keybytes = ktp->enc->keybytes;
+ keylength = ktp->enc->keylength;
+
+ concatlen = string->length + (salt ? salt->length : 0);
+
+ concat = k5alloc(concatlen, &ret);
+ if (ret != 0)
+ goto cleanup;
+ foldstring = k5alloc(keybytes, &ret);
+ if (ret != 0)
+ goto cleanup;
+ foldkeydata = k5alloc(keylength, &ret);
+ if (ret != 0)
+ goto cleanup;
+
+ /* construct input string ( = string + salt), fold it, make_key it */
+
+ memcpy(concat, string->data, string->length);
+ if (salt)
+ memcpy(concat + string->length, salt->data, salt->length);
+
+ krb5int_nfold(concatlen*8, concat, keybytes*8, foldstring);
+
+ indata.length = keybytes;
+ indata.data = (char *) foldstring;
+ foldkeyblock.length = keylength;
+ foldkeyblock.contents = foldkeydata;
+ foldkeyblock.enctype = ktp->etype;
+
+ ret = ktp->rand2key(&indata, &foldkeyblock);
+ if (ret != 0)
+ goto cleanup;
+
+ ret = krb5_k_create_key(NULL, &foldkeyblock, &foldkey);
+ if (ret != 0)
+ goto cleanup;
+
+ /* now derive the key from this one */
+
+ indata.length = kerberos_len;
+ indata.data = (char *) kerberos;
+
+ ret = krb5int_derive_keyblock(ktp->enc, foldkey, keyblock, &indata,
+ DERIVE_RFC3961);
+ if (ret != 0)
+ memset(keyblock->contents, 0, keyblock->length);
+
+cleanup:
+ zapfree(concat, concatlen);
+ zapfree(foldstring, keybytes);
+ zapfree(foldkeydata, keylength);
+ krb5_k_free_key(NULL, foldkey);
+ return ret;
+}
+
+
+#define MAX_ITERATION_COUNT 0x1000000L
+
+static krb5_error_code
+pbkdf2_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string,
+ const krb5_data *salt, const krb5_data *pepper,
+ const krb5_data *params, krb5_keyblock *key,
+ enum deriv_alg deriv_alg, unsigned long def_iter_count)
+{
+ unsigned long iter_count;
+ krb5_data out;
+ static const krb5_data usage = { KV5M_DATA, 8, "kerberos" };
+ krb5_key tempkey = NULL;
+ krb5_error_code err;
+ krb5_data sandp = empty_data();
+
+ if (params) {
+ unsigned char *p = (unsigned char *) params->data;
+ if (params->length != 4)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+ /* The first two need casts in case 'int' is 16 bits. */
+ iter_count = load_32_be(p);
+ if (iter_count == 0) {
+ iter_count = (1UL << 16) << 16;
+ if (((iter_count >> 16) >> 16) != 1)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+ }
+ } else
+ iter_count = def_iter_count;
+
+ /* This is not a protocol specification constraint; this is an
+ implementation limit, which should eventually be controlled by
+ a config file. */
+ if (iter_count >= MAX_ITERATION_COUNT)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+
+ /* Use the output keyblock contents for temporary space. */
+ out.data = (char *) key->contents;
+ out.length = key->length;
+ if (out.length != 16 && out.length != 32)
+ return KRB5_CRYPTO_INTERNAL;
+
+ if (pepper != NULL) {
+ err = alloc_data(&sandp, pepper->length + 1 + salt->length);
+ if (err)
+ return err;
+
+ memcpy(sandp.data, pepper->data, pepper->length);
+ sandp.data[pepper->length] = '\0';
+ memcpy(&sandp.data[pepper->length + 1], salt->data, salt->length);
+
+ salt = &sandp;
+ }
+
+ err = krb5int_pbkdf2_hmac_sha1 (&out, iter_count, string, salt);
+ if (err)
+ goto cleanup;
+
+ err = krb5_k_create_key (NULL, key, &tempkey);
+ if (err)
+ goto cleanup;
+
+ err = krb5int_derive_keyblock(ktp->enc, tempkey, key, &usage, deriv_alg);
+
+cleanup:
+ if (sandp.data)
+ free(sandp.data);
+ if (err)
+ memset (out.data, 0, out.length);
+ krb5_k_free_key (NULL, tempkey);
+ return err;
+}
+
+krb5_error_code
+krb5int_aes_string_to_key(const struct krb5_keytypes *ktp,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key)
+{
+ return pbkdf2_string_to_key(ktp, string, salt, NULL, params, key,
+ DERIVE_RFC3961, 4096);
+}
+
+#ifdef CAMELLIA
+krb5_error_code
+krb5int_camellia_string_to_key(const struct krb5_keytypes *ktp,
+ const krb5_data *string,
+ const krb5_data *salt,
+ const krb5_data *params,
+ krb5_keyblock *key)
+{
+ krb5_data pepper = string2data(ktp->name);
+
+ return pbkdf2_string_to_key(ktp, string, salt, &pepper, params, key,
+ DERIVE_SP800_108_CMAC, 32768);
+}
+#endif
Copied: trunk/src/lib/crypto/krb/s2k_rc4.c (from rev 24677, trunk/src/lib/crypto/krb/arcfour/arcfour_s2k.c)
===================================================================
--- trunk/src/lib/crypto/krb/s2k_rc4.c (rev 0)
+++ trunk/src/lib/crypto/krb/s2k_rc4.c 2011-03-05 13:31:02 UTC (rev 24679)
@@ -0,0 +1,37 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#include "crypto_int.h"
+#include "k5-utf8.h"
+
+krb5_error_code
+krb5int_arcfour_string_to_key(const struct krb5_keytypes *ktp,
+ const krb5_data *string, const krb5_data *salt,
+ const krb5_data *params, krb5_keyblock *key)
+{
+ krb5_error_code err = 0;
+ krb5_crypto_iov iov;
+ krb5_data hash_out;
+ unsigned char *copystr;
+ size_t copystrlen;
+
+ if (params != NULL)
+ return KRB5_ERR_BAD_S2K_PARAMS;
+
+ if (key->length != 16)
+ return (KRB5_BAD_MSIZE);
+
+ /* We ignore salt per the Microsoft spec. */
+ err = krb5int_utf8cs_to_ucs2les(string->data, string->length, ©str,
+ ©strlen);
+ if (err)
+ return err;
+
+ /* the actual MD4 hash of the data */
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
+ iov.data = make_data(copystr, copystrlen);
+ hash_out = make_data(key->contents, key->length);
+ err = krb5int_hash_md4.hash(&iov, 1, &hash_out);
+
+ /* Zero out the data behind us */
+ zapfree(copystr, copystrlen);
+ return err;
+}
More information about the cvs-krb5
mailing list