int gssEapEncrypt(krb5_context context, int dce_style, size_t ec, size_t rrc, #ifdef HAVE_HEIMDAL_VERSION krb5_crypto crypto, #else krb5_keyblock *crypto, #endif int usage, gss_iov_buffer_desc *iov, int iov_count) { krb5_error_code code; size_t kiov_count; krb5_crypto_iov *kiov = NULL; code = mapIov(context, dce_style, ec, rrc, crypto, iov, iov_count, &kiov, &kiov_count); if (code != 0) goto cleanup; #ifdef HAVE_HEIMDAL_VERSION code = krb5_encrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL); #else code = krb5_c_encrypt_iov(context, crypto, usage, NULL, kiov, kiov_count); #endif if (code != 0) goto cleanup; cleanup: if (kiov != NULL) GSSEAP_FREE(kiov); return code; }
static int iov_test(krb5_context context) { krb5_enctype enctype = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96; krb5_error_code ret; krb5_crypto crypto; krb5_keyblock key; krb5_data signonly, in, in2; krb5_crypto_iov iov[6]; size_t len, i; unsigned char *base, *p; ret = krb5_generate_random_keyblock(context, enctype, &key); if (ret) krb5_err(context, 1, ret, "krb5_generate_random_keyblock"); ret = krb5_crypto_init(context, &key, 0, &crypto); if (ret) krb5_err(context, 1, ret, "krb5_crypto_init"); ret = krb5_crypto_length(context, crypto, KRB5_CRYPTO_TYPE_HEADER, &len); if (ret) krb5_err(context, 1, ret, "krb5_crypto_length"); signonly.data = "This should be signed"; signonly.length = strlen(signonly.data); in.data = "inputdata"; in.length = strlen(in.data); in2.data = "INPUTDATA"; in2.length = strlen(in2.data); memset(iov, 0, sizeof(iov)); iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data = in; iov[2].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; iov[2].data = signonly; iov[3].flags = KRB5_CRYPTO_TYPE_EMPTY; iov[4].flags = KRB5_CRYPTO_TYPE_PADDING; iov[5].flags = KRB5_CRYPTO_TYPE_TRAILER; ret = krb5_crypto_length_iov(context, crypto, iov, sizeof(iov)/sizeof(iov[0])); if (ret) krb5_err(context, 1, ret, "krb5_crypto_length_iov"); for (len = 0, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) continue; len += iov[i].data.length; } base = emalloc(len); /* * Allocate data for the fields */ for (p = base, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) continue;; iov[i].data.data = p; p += iov[i].data.length; } assert(iov[1].data.length == in.length); memcpy(iov[1].data.data, in.data, iov[1].data.length); /* * Encrypt */ ret = krb5_encrypt_iov_ivec(context, crypto, 7, iov, sizeof(iov)/sizeof(iov[0]), NULL); if (ret) krb5_err(context, 1, ret, "krb5_encrypt_iov_ivec"); /* * Decrypt */ ret = krb5_decrypt_iov_ivec(context, crypto, 7, iov, sizeof(iov)/sizeof(iov[0]), NULL); if (ret) krb5_err(context, 1, ret, "krb5_decrypt_iov_ivec"); /* * Verify data */ if (krb5_data_cmp(&iov[1].data, &in) != 0) krb5_errx(context, 1, "decrypted data not same"); /* * Free memory */ free(base); /* Set up for second try */ iov[3].flags = KRB5_CRYPTO_TYPE_DATA; iov[3].data = in; ret = krb5_crypto_length_iov(context, crypto, iov, sizeof(iov)/sizeof(iov[0])); if (ret) krb5_err(context, 1, ret, "krb5_crypto_length_iov"); for (len = 0, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) continue; len += iov[i].data.length; } base = emalloc(len); /* * Allocate data for the fields */ for (p = base, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) continue;; iov[i].data.data = p; p += iov[i].data.length; } assert(iov[1].data.length == in.length); memcpy(iov[1].data.data, in.data, iov[1].data.length); assert(iov[3].data.length == in2.length); memcpy(iov[3].data.data, in2.data, iov[3].data.length); /* * Encrypt */ ret = krb5_encrypt_iov_ivec(context, crypto, 7, iov, sizeof(iov)/sizeof(iov[0]), NULL); if (ret) krb5_err(context, 1, ret, "krb5_encrypt_iov_ivec"); /* * Decrypt */ ret = krb5_decrypt_iov_ivec(context, crypto, 7, iov, sizeof(iov)/sizeof(iov[0]), NULL); if (ret) krb5_err(context, 1, ret, "krb5_decrypt_iov_ivec"); /* * Verify data */ if (krb5_data_cmp(&iov[1].data, &in) != 0) krb5_errx(context, 1, "decrypted data 2.1 not same"); if (krb5_data_cmp(&iov[3].data, &in2) != 0) krb5_errx(context, 1, "decrypted data 2.2 not same"); /* * Free memory */ free(base); krb5_crypto_destroy(context, crypto); krb5_free_keyblock_contents(context, &key); return 0; }
static int krb_enc_iov2(krb5_context context, krb5_crypto crypto, unsigned usage, size_t cipher_len, krb5_data *clear) { krb5_crypto_iov iov[4]; krb5_data decrypt; int ret; char *p, *q; size_t len, i; p = clear->data; len = clear->length; iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length); iov[0].data.data = emalloc(iov[0].data.length); iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data.length = len; iov[1].data.data = emalloc(iov[1].data.length); memcpy(iov[1].data.data, p, iov[1].data.length); /* padding buffer */ iov[2].flags = KRB5_CRYPTO_TYPE_PADDING; krb5_crypto_length(context, crypto, KRB5_CRYPTO_TYPE_PADDING, &iov[2].data.length); iov[2].data.data = emalloc(iov[2].data.length); iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER; krb5_crypto_length(context, crypto, iov[3].flags, &iov[3].data.length); iov[3].data.data = emalloc(iov[3].data.length); ret = krb5_encrypt_iov_ivec(context, crypto, usage, iov, sizeof(iov)/sizeof(iov[0]), NULL); if (ret) errx(1, "encrypt iov failed: %d", ret); /* check len */ for (i = 0, len = 0; i < sizeof(iov)/sizeof(iov[0]); i++) len += iov[i].data.length; if (len != cipher_len) errx(1, "cipher len wrong"); /* * Plain decrypt */ p = q = emalloc(len); for (i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) { memcpy(q, iov[i].data.data, iov[i].data.length); q += iov[i].data.length; } ret = krb5_decrypt(context, crypto, usage, p, len, &decrypt); if (ret) krb5_err(context, 1, ret, "krb5_decrypt"); else krb5_data_free(&decrypt); free(p); /* * Now decrypt use iov */ /* padding turn into data */ p = q = emalloc(iov[1].data.length + iov[2].data.length); memcpy(q, iov[1].data.data, iov[1].data.length); q += iov[1].data.length; memcpy(q, iov[2].data.data, iov[2].data.length); free(iov[1].data.data); free(iov[2].data.data); iov[1].data.data = p; iov[1].data.length += iov[2].data.length; iov[2].flags = KRB5_CRYPTO_TYPE_EMPTY; iov[2].data.length = 0; ret = krb5_decrypt_iov_ivec(context, crypto, usage, iov, sizeof(iov)/sizeof(iov[0]), NULL); free(iov[0].data.data); free(iov[3].data.data); if (ret) krb5_err(context, 1, ret, "decrypt iov failed: %d", ret); if (clear->length != iov[1].data.length) errx(1, "length incorrect"); p = clear->data; if (memcmp(iov[1].data.data, p, iov[1].data.length) != 0) errx(1, "iov[1] incorrect"); free(iov[1].data.data); return 0; }