crypt_mbedtls.c 3.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright (c) Edward Thomson.  All rights reserved.
 *
 * This file is part of ntlmclient, distributed under the MIT license.
 * For full terms and copyright information, and for third-party
 * copyright information, see the included LICENSE.txt file.
 */

#include <stdlib.h>
#include <string.h>

#include "mbedtls/ctr_drbg.h"
#include "mbedtls/des.h"
#include "mbedtls/entropy.h"
#include "mbedtls/md4.h"

#include "ntlm.h"
#include "crypt.h"

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
bool ntlm_crypt_init(ntlm_client *ntlm)
{
	const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);

	mbedtls_md_init(&ntlm->crypt_ctx.hmac);

	if (mbedtls_md_setup(&ntlm->crypt_ctx.hmac, info, 1) != 0) {
		ntlm_client_set_errmsg(ntlm, "could not setup mbedtls digest");
		return false;
	}

	return true;
}


35 36
bool ntlm_random_bytes(
	unsigned char *out,
37
	ntlm_client *ntlm,
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
	size_t len)
{
	mbedtls_ctr_drbg_context ctr_drbg;
	mbedtls_entropy_context entropy;
	bool ret = true;

	const unsigned char personalization[] = {
		0xec, 0xb5, 0xd1, 0x0b, 0x8f, 0x15, 0x1f, 0xc2,
		0xe4, 0x8e, 0xec, 0x36, 0xf7, 0x0a, 0x45, 0x9a,
		0x1f, 0xe1, 0x35, 0x58, 0xb1, 0xcb, 0xfd, 0x8a,
		0x57, 0x5c, 0x75, 0x7d, 0x2f, 0xc9, 0x70, 0xac
	};

	mbedtls_ctr_drbg_init(&ctr_drbg);
	mbedtls_entropy_init(&entropy);

	if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
		&entropy, personalization, sizeof(personalization)) ||
		mbedtls_ctr_drbg_random(&ctr_drbg, out, len)) {
		ntlm_client_set_errmsg(ntlm, "random generation failed");
		ret = false;
	}

	mbedtls_entropy_free(&entropy);
	mbedtls_ctr_drbg_free(&ctr_drbg);

	return ret;
}

bool ntlm_des_encrypt(
	ntlm_des_block *out,
69
	ntlm_client *ntlm,
70 71 72 73 74 75 76 77 78
	ntlm_des_block *plaintext,
	ntlm_des_block *key)
{
	mbedtls_des_context ctx;
	bool success = false;

	mbedtls_des_init(&ctx);

	if (mbedtls_des_setkey_enc(&ctx, *key) ||
79 80
	    mbedtls_des_crypt_ecb(&ctx, *plaintext, *out)) {
		ntlm_client_set_errmsg(ntlm, "DES encryption failed");
81
		goto done;
82
	}
83 84 85 86 87 88 89 90 91 92

	success = true;

done:
	mbedtls_des_free(&ctx);
	return success;
}

bool ntlm_md4_digest(
	unsigned char out[CRYPT_MD4_DIGESTSIZE],
93
	ntlm_client *ntlm,
94 95 96 97 98
	const unsigned char *in,
	size_t in_len)
{
	mbedtls_md4_context ctx;

99 100
	NTLM_UNUSED(ntlm);

101 102 103 104 105 106 107 108 109 110
	mbedtls_md4_init(&ctx);
	mbedtls_md4_starts(&ctx);
	mbedtls_md4_update(&ctx, in, in_len);
	mbedtls_md4_finish(&ctx, out);
	mbedtls_md4_free(&ctx);

	return true;
}

bool ntlm_hmac_md5_init(
111
	ntlm_client *ntlm,
112 113 114
	const unsigned char *key,
	size_t key_len)
{
115 116 117 118 119 120 121
	if (ntlm->crypt_ctx.hmac_initialized) {
		if (mbedtls_md_hmac_reset(&ntlm->crypt_ctx.hmac))
			return false;
	}

	ntlm->crypt_ctx.hmac_initialized = !mbedtls_md_hmac_starts(&ntlm->crypt_ctx.hmac, key, key_len);
	return ntlm->crypt_ctx.hmac_initialized;
122 123 124
}

bool ntlm_hmac_md5_update(
125
	ntlm_client *ntlm,
126 127 128
	const unsigned char *in,
	size_t in_len)
{
129
	return !mbedtls_md_hmac_update(&ntlm->crypt_ctx.hmac, in, in_len);
130 131 132 133 134
}

bool ntlm_hmac_md5_final(
	unsigned char *out,
	size_t *out_len,
135
	ntlm_client *ntlm)
136 137 138 139
{
	if (*out_len < CRYPT_MD5_DIGESTSIZE)
		return false;

140
	return !mbedtls_md_hmac_finish(&ntlm->crypt_ctx.hmac, out);
141 142
}

143
void ntlm_crypt_shutdown(ntlm_client *ntlm)
144
{
145
	mbedtls_md_free(&ntlm->crypt_ctx.hmac);
146
}