1 /* 2 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 #include <k5-int.h> 9 10 #include <sys/crypto/api.h> 11 12 #include <sys/callb.h> 13 #include <sys/uio.h> 14 15 int 16 k5_ef_hash(krb5_context context, int icount, 17 const krb5_data *input, 18 krb5_data *output) 19 { 20 int i; 21 int rv = CRYPTO_FAILED; 22 iovec_t v1, v2; 23 crypto_data_t d1, d2; 24 crypto_mechanism_t mech; 25 crypto_context_t ctxp; 26 27 KRB5_LOG0(KRB5_INFO, "k5_ef_hash() start"); 28 29 bzero(&d1, sizeof (d1)); 30 bzero(&d2, sizeof (d2)); 31 32 v2.iov_base = (void *)output->data; 33 v2.iov_len = output->length; 34 35 d2.cd_format = CRYPTO_DATA_RAW; 36 d2.cd_offset = 0; 37 d2.cd_length = output->length; 38 d2.cd_raw = v2; 39 40 mech.cm_type = context->kef_cksum_mt; 41 if (mech.cm_type == CRYPTO_MECH_INVALID) { 42 KRB5_LOG(KRB5_ERR, 43 "k5_ef_hash() invalid mech specified: 0x%llx", 44 (long long)context->kef_hash_mt); 45 return (CRYPTO_FAILED); 46 } 47 mech.cm_param = 0; 48 mech.cm_param_len = 0; 49 50 rv = crypto_digest_init(&mech, &ctxp, NULL); 51 if (rv != CRYPTO_SUCCESS) { 52 KRB5_LOG(KRB5_ERR, "crypto_digest_init error: %0x", rv); 53 return (rv); 54 } 55 56 for (i = 0; i < icount; i++) { 57 v1.iov_base = (void *)input[i].data; 58 v1.iov_len = input[i].length; 59 d1.cd_length = input[i].length; 60 d1.cd_format = CRYPTO_DATA_RAW; 61 d1.cd_offset = 0; 62 d1.cd_raw = v1; 63 64 rv = crypto_digest_update(ctxp, &d1, NULL); 65 if (rv != CRYPTO_SUCCESS) { 66 KRB5_LOG(KRB5_ERR, 67 "crypto_digest_update error: %0x", rv); 68 crypto_cancel_ctx(ctxp); 69 return (rv); 70 } 71 } 72 73 rv = crypto_digest_final(ctxp, &d2, NULL); 74 /* 75 * crypto_digest_final() internally destroys the context. So, we 76 * do not use the context any more. This means we do not call 77 * crypto_cancel_ctx() for the failure case here unlike the failure 78 * case of crypto_digest_update() where we do. 79 */ 80 if (rv != CRYPTO_SUCCESS) { 81 KRB5_LOG(KRB5_ERR, "crypto_digest_final error: %0x", rv); 82 } 83 84 return (rv); 85 } 86 87 int 88 k5_ef_mac(krb5_context context, 89 krb5_keyblock *key, 90 krb5_data *ivec, 91 const krb5_data *input, 92 krb5_data *output) 93 { 94 int rv; 95 iovec_t v1, v2; 96 crypto_data_t d1, d2; 97 crypto_mechanism_t mech; 98 99 KRB5_LOG0(KRB5_INFO, "k5_ef_mac() start"); 100 101 ASSERT(input != NULL); 102 ASSERT(ivec != NULL); 103 ASSERT(output != NULL); 104 105 v2.iov_base = (void *)output->data; 106 v2.iov_len = output->length; 107 108 bzero(&d1, sizeof (d1)); 109 bzero(&d2, sizeof (d2)); 110 111 d2.cd_format = CRYPTO_DATA_RAW; 112 d2.cd_offset = 0; 113 d2.cd_length = output->length; 114 d2.cd_raw = v2; 115 116 mech.cm_type = context->kef_hash_mt; 117 if (mech.cm_type == CRYPTO_MECH_INVALID) { 118 KRB5_LOG(KRB5_ERR, 119 "k5_ef_mac() invalid mech specified: 0x%llx", 120 (long long)context->kef_hash_mt); 121 return (CRYPTO_FAILED); 122 } 123 124 mech.cm_param = ivec->data; 125 mech.cm_param_len = ivec->length; 126 127 v1.iov_base = (void *)input->data; 128 v1.iov_len = input->length; 129 130 d1.cd_format = CRYPTO_DATA_RAW; 131 d1.cd_offset = 0; 132 d1.cd_length = input->length; 133 d1.cd_raw = v1; 134 135 rv = crypto_mac(&mech, &d1, &key->kef_key, key->key_tmpl, &d2, NULL); 136 if (rv != CRYPTO_SUCCESS) { 137 KRB5_LOG(KRB5_ERR, 138 "k5_ef_mac(): crypto_mac error: %0x", rv); 139 } 140 141 return (rv); 142 } 143