| /* |
| * 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" |
| |
| bool ntlm_random_bytes( |
| ntlm_client *ntlm, |
| unsigned char *out, |
| 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, |
| 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) || |
| mbedtls_des_crypt_ecb(&ctx, *plaintext, *out)) |
| goto done; |
| |
| success = true; |
| |
| done: |
| mbedtls_des_free(&ctx); |
| return success; |
| } |
| |
| bool ntlm_md4_digest( |
| unsigned char out[CRYPT_MD4_DIGESTSIZE], |
| const unsigned char *in, |
| size_t in_len) |
| { |
| mbedtls_md4_context ctx; |
| |
| 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; |
| } |
| |
| ntlm_hmac_ctx *ntlm_hmac_ctx_init(void) |
| { |
| ntlm_hmac_ctx *ctx; |
| const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); |
| |
| if ((ctx = calloc(1, sizeof(ntlm_hmac_ctx))) == NULL) |
| return NULL; |
| |
| mbedtls_md_init(&ctx->mbed); |
| |
| if (mbedtls_md_setup(&ctx->mbed, info, 1) != 0) { |
| free(ctx); |
| return false; |
| } |
| |
| return ctx; |
| } |
| |
| bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx) |
| { |
| return !mbedtls_md_hmac_reset(&ctx->mbed); |
| } |
| |
| bool ntlm_hmac_md5_init( |
| ntlm_hmac_ctx *ctx, |
| const unsigned char *key, |
| size_t key_len) |
| { |
| return !mbedtls_md_hmac_starts(&ctx->mbed, key, key_len); |
| } |
| |
| bool ntlm_hmac_md5_update( |
| ntlm_hmac_ctx *ctx, |
| const unsigned char *in, |
| size_t in_len) |
| { |
| return !mbedtls_md_hmac_update(&ctx->mbed, in, in_len); |
| } |
| |
| bool ntlm_hmac_md5_final( |
| unsigned char *out, |
| size_t *out_len, |
| ntlm_hmac_ctx *ctx) |
| { |
| if (*out_len < CRYPT_MD5_DIGESTSIZE) |
| return false; |
| |
| return !mbedtls_md_hmac_finish(&ctx->mbed, out); |
| } |
| |
| void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx) |
| { |
| if (ctx) { |
| mbedtls_md_free(&ctx->mbed); |
| free(ctx); |
| } |
| } |