/* * 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 <openssl/rand.h> #include <openssl/des.h> #include <openssl/md4.h> #include <openssl/hmac.h> #include <openssl/err.h> #include "ntlm.h" #include "compat.h" #include "util.h" #include "crypt.h" bool ntlm_random_bytes( ntlm_client *ntlm, unsigned char *out, size_t len) { int rc = RAND_bytes(out, len); if (rc != 1) { ntlm_client_set_errmsg(ntlm, ERR_lib_error_string(ERR_get_error())); return false; } return true; } bool ntlm_des_encrypt( ntlm_des_block *out, ntlm_des_block *plaintext, ntlm_des_block *key) { DES_key_schedule keysched; memset(out, 0, sizeof(ntlm_des_block)); DES_set_key(key, &keysched); DES_ecb_encrypt(plaintext, out, &keysched, DES_ENCRYPT); return true; } bool ntlm_md4_digest( unsigned char out[CRYPT_MD4_DIGESTSIZE], const unsigned char *in, size_t in_len) { MD4(in, in_len, out); return true; } #if OPENSSL_VERSION_NUMBER < 0x10100000L static inline void HMAC_CTX_free(HMAC_CTX *ctx) { if (ctx) HMAC_CTX_cleanup(ctx); free(ctx); } static inline int HMAC_CTX_reset(HMAC_CTX *ctx) { HMAC_CTX_cleanup(ctx); memzero(ctx, sizeof(HMAC_CTX)); return 1; } static inline HMAC_CTX *HMAC_CTX_new(void) { return calloc(1, sizeof(HMAC_CTX)); } #endif ntlm_hmac_ctx *ntlm_hmac_ctx_init(void) { return HMAC_CTX_new(); } bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx) { return HMAC_CTX_reset(ctx); } bool ntlm_hmac_md5_init( ntlm_hmac_ctx *ctx, const unsigned char *key, size_t key_len) { return HMAC_Init_ex(ctx, key, key_len, EVP_md5(), NULL); } bool ntlm_hmac_md5_update( ntlm_hmac_ctx *ctx, const unsigned char *in, size_t in_len) { return HMAC_Update(ctx, in, in_len); } bool ntlm_hmac_md5_final( unsigned char *out, size_t *out_len, ntlm_hmac_ctx *ctx) { unsigned int len; if (*out_len < CRYPT_MD5_DIGESTSIZE) return false; if (!HMAC_Final(ctx, out, &len)) return false; *out_len = len; return true; } void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx) { HMAC_CTX_free(ctx); }