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