combine_keys.c revision 159d09a20817016f09b3ea28d1bdada4a336bb91
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the software,
* derivative works or modified versions, and any portions thereof.
*
* NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
* DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
* RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Key combination function.
*
* If Key1 and Key2 are two keys to be combined, the algorithm to combine
* them is as follows.
*
* Definitions:
*
* k-truncate is defined as truncating to the key size the input.
*
* DR is defined as the generate "random" data from a key
* (defined in crypto draft)
*
* DK is defined as the key derivation function (krb5_derive_key())
*
* (note: | means "concatenate")
*
* Combine key algorithm:
*
* R1 = DR(Key1, n-fold(Key2)) [ Output is length of Key1 ]
* R2 = DR(Key2, n-fold(Key1)) [ Output is length of Key2 ]
*
* rnd = n-fold(R1 | R2) [ Note: output size of nfold must be appropriately
* sized for random-to-key function ]
* tkey = random-to-key(rnd)
* Combine-Key(Key1, Key2) = DK(tkey, CombineConstant)
*
* CombineConstant is defined as the byte string:
*
* { 0x63 0x6f 0x6d 0x62 0x69 0x6e 0x65 }, which corresponds to the
* ASCII encoding of the string "combine"
*/
#include "k5-int.h"
#include "etypes.h"
#include "dk.h"
/* Solaris Kerberos */
static krb5_error_code dr
/*
* We only support this combine_keys algorithm for des and 3des keys.
* Everything else should use the PRF defined in the crypto framework.
* We don't implement that yet.
*/
{
switch (e) {
case ENCTYPE_DES_CBC_CRC:
case ENCTYPE_DES_CBC_MD4:
case ENCTYPE_DES_CBC_MD5:
case ENCTYPE_DES3_CBC_SHA1:
return 1;
default:
return 0;
}
}
{
const struct krb5_enc_provider *enc;
int i, myalloc = 0;
return (KRB5_CRYPTO_INTERNAL);
return (KRB5_CRYPTO_INTERNAL);
/*
* Find our encryption algorithm
*/
for (i = 0; i < krb5_enctypes_length; i++) {
break;
}
if (i == krb5_enctypes_length)
return (KRB5_BAD_ENCTYPE);
/*
* Allocate and set up buffers
*/
return (ENOMEM);
return (ENOMEM);
}
return (ENOMEM);
}
return (ENOMEM);
}
return (ENOMEM);
}
/*
* Get R1 and R2 (by running the input keys through the DR algorithm.
* Note this is most of derive-key, but not all.
*/
/* Solaris Kerberos */
goto cleanup;
#if 0
{
int i;
printf("R1 =");
for (i = 0; i < keybytes; i++)
printf("\n");
}
#endif
/* Solaris Kerberos */
goto cleanup;
#if 0
{
int i;
printf("R2 =");
for (i = 0; i < keybytes; i++)
printf("\n");
}
#endif
/*
* Concatenate the two keys together, and then run them through
* n-fold to reduce them to a length appropriate for the random-to-key
* operation. Note here that krb5_nfold() takes sizes in bits, hence
* the multiply by 8.
*/
#if 0
{
int i;
printf("rnd =");
for (i = 0; i < keybytes; i++)
printf("\n");
}
#endif
/*
* Run the "random" bits through random-to-key to produce a encryption
* key.
*/
/* Solaris Kerberos */
goto cleanup;
#if 0
{
int i;
printf("tkey =");
printf("\n");
}
#endif
/*
* Run through derive-key one more time to produce the final key.
* Note that the input to derive-key is the ASCII string "combine".
*/
/*
* Just FYI: _if_ we have space here in the key, then simply use it
* without modification. But if the key is blank (no allocated storage)
* then allocate some memory for it. This allows programs to use one of
* the existing keys as the output key, _or_ pass in a blank keyblock
* for us to allocate. It's easier for us to allocate it since we already
* know the crypto library internals
*/
goto cleanup;
}
myalloc = 1;
}
/* Solaris Kerberos */
if (myalloc) {
}
goto cleanup;
}
#if 0
{
int i;
printf("output =");
printf("\n");
}
#endif
ret = 0;
return (ret);
}
/*
* Our DR function; mostly taken from derive.c
*/
/* Solaris Kerberos */
static krb5_error_code dr
const struct krb5_enc_provider *enc,
const krb5_keyblock *inkey,
unsigned char *out,
const krb5_data *in_constant)
{
unsigned char *inblockdata, *outblockdata;
/* allocate and set up buffers */
return(ENOMEM);
return(ENOMEM);
}
/* initialize the input block */
} else {
}
/* loop encrypting the blocks until enough key bytes are generated */
n = 0;
while (n < keybytes) {
/* Solaris Kerberos */
break;
}
}
/* clean memory, free resources and exit */
return(0);
}