17c478bd9Sstevel@tonic-gate /*
2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate * lib/crypto/aes/aes_s2k.c
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Copyright 2003 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate * All Rights Reserved.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
177c478bd9Sstevel@tonic-gate *
187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
307c478bd9Sstevel@tonic-gate * or implied warranty.
317c478bd9Sstevel@tonic-gate *
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * krb5int_aes_string_to_key
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
36*159d09a2SMark Phalan #include "k5-int.h"
37*159d09a2SMark Phalan #include "dk.h"
38*159d09a2SMark Phalan #include "aes_s2k.h"
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate #define DEFAULT_ITERATION_COUNT 4096 /* was 0xb000L in earlier drafts */
417c478bd9Sstevel@tonic-gate #define MAX_ITERATION_COUNT 0x1000000L
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate krb5_error_code
krb5int_aes_string_to_key(krb5_context context,const struct krb5_enc_provider * enc,const krb5_data * string,const krb5_data * salt,const krb5_data * params,krb5_keyblock * key)447c478bd9Sstevel@tonic-gate krb5int_aes_string_to_key(krb5_context context,
457c478bd9Sstevel@tonic-gate const struct krb5_enc_provider *enc,
467c478bd9Sstevel@tonic-gate const krb5_data *string,
477c478bd9Sstevel@tonic-gate const krb5_data *salt,
487c478bd9Sstevel@tonic-gate const krb5_data *params,
497c478bd9Sstevel@tonic-gate krb5_keyblock *key)
507c478bd9Sstevel@tonic-gate {
517c478bd9Sstevel@tonic-gate unsigned long iter_count;
527c478bd9Sstevel@tonic-gate krb5_data out;
537c478bd9Sstevel@tonic-gate static const krb5_data usage = { KV5M_DATA, 8, "kerberos" };
547c478bd9Sstevel@tonic-gate krb5_error_code err;
55*159d09a2SMark Phalan /* Solaris Kerberos */
567c478bd9Sstevel@tonic-gate krb5_keyblock *inkey = NULL;
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate if (params) {
597c478bd9Sstevel@tonic-gate unsigned char *p = (unsigned char *) params->data;
607c478bd9Sstevel@tonic-gate if (params->length != 4)
617c478bd9Sstevel@tonic-gate return KRB5_ERR_BAD_S2K_PARAMS;
62*159d09a2SMark Phalan /* The first two need casts in case 'int' is 16 bits. */
63*159d09a2SMark Phalan iter_count = (((unsigned long)p[0] << 24)
64*159d09a2SMark Phalan | ((unsigned long)p[1] << 16)
65*159d09a2SMark Phalan | (p[2] << 8)
66*159d09a2SMark Phalan | (p[3]));
677c478bd9Sstevel@tonic-gate if (iter_count == 0) {
687c478bd9Sstevel@tonic-gate /*
697c478bd9Sstevel@tonic-gate iter_count = (1L << 16) << 16;
707c478bd9Sstevel@tonic-gate if (((iter_count >> 16) >> 16) != 1)
717c478bd9Sstevel@tonic-gate return KRB5_ERR_BAD_S2K_PARAMS;
727c478bd9Sstevel@tonic-gate */
737c478bd9Sstevel@tonic-gate iter_count = DEFAULT_ITERATION_COUNT;
747c478bd9Sstevel@tonic-gate }
757c478bd9Sstevel@tonic-gate } else
767c478bd9Sstevel@tonic-gate iter_count = DEFAULT_ITERATION_COUNT;
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate /* This is not a protocol specification constraint; this is an
797c478bd9Sstevel@tonic-gate implementation limit, which should eventually be controlled by
807c478bd9Sstevel@tonic-gate a config file. */
817c478bd9Sstevel@tonic-gate if (iter_count >= MAX_ITERATION_COUNT)
827c478bd9Sstevel@tonic-gate return KRB5_ERR_BAD_S2K_PARAMS;
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate /*
857c478bd9Sstevel@tonic-gate * Dense key space, no parity bits or anything, so take a shortcut
867c478bd9Sstevel@tonic-gate * and use the key contents buffer for the generated bytes.
877c478bd9Sstevel@tonic-gate */
88*159d09a2SMark Phalan /* Solaris Kerberos */
897c478bd9Sstevel@tonic-gate if (key->length != 16 && key->length != 32)
907c478bd9Sstevel@tonic-gate return KRB5_CRYPTO_INTERNAL;
917c478bd9Sstevel@tonic-gate out.data = (char *) key->contents;
927c478bd9Sstevel@tonic-gate out.length = key->length;
93*159d09a2SMark Phalan /* Solaris Kerberos */
947c478bd9Sstevel@tonic-gate err = krb5int_pbkdf2_hmac_sha1 (context, &out, iter_count, key->enctype,
957c478bd9Sstevel@tonic-gate string, salt);
967c478bd9Sstevel@tonic-gate if (err) {
977c478bd9Sstevel@tonic-gate memset(out.data, 0, out.length);
987c478bd9Sstevel@tonic-gate return err;
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate /*
102*159d09a2SMark Phalan * Solaris Kerberos:
1037c478bd9Sstevel@tonic-gate * The derive key operation below will not work correctly
1047c478bd9Sstevel@tonic-gate * if the input and output key pointers are to the same
1057c478bd9Sstevel@tonic-gate * data. This is because the key object handle (PKCS#11)
1067c478bd9Sstevel@tonic-gate * gets out-of-sync with the original key when the contents
1077c478bd9Sstevel@tonic-gate * are modified. We copy the original key here for use
1087c478bd9Sstevel@tonic-gate * below in the derive_key step, then we free this key
1097c478bd9Sstevel@tonic-gate * before exiting.
1107c478bd9Sstevel@tonic-gate */
1117c478bd9Sstevel@tonic-gate err = krb5_copy_keyblock(context, key, &inkey);
1127c478bd9Sstevel@tonic-gate if (err) {
1137c478bd9Sstevel@tonic-gate memset(out.data, 0, out.length);
1147c478bd9Sstevel@tonic-gate return err;
1157c478bd9Sstevel@tonic-gate }
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate err = krb5_derive_key (context, enc, inkey, key, &usage);
1187c478bd9Sstevel@tonic-gate if (err) {
1197c478bd9Sstevel@tonic-gate memset(out.data, 0, out.length);
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate krb5_free_keyblock(context, inkey);
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate return (err);
1247c478bd9Sstevel@tonic-gate }
125