You can use the Windows Cryptography library for this. For instance, here's a minimal unit to calculate MD5 hashes:
unit MD5;
interface
uses
  SysUtils, Math, Windows, Classes;
type
  TMD5Hash = array [0..15] of Byte;
function MD5Hash(Stream: TStream): TMD5Hash; overload;
function MD5Hash(const Bytes: TBytes): TMD5Hash; overload;
function MD5Hash(const Str: RawByteString): TMD5Hash; overload;
function MD5ToString(const Hash: TMD5Hash): string;
implementation
type
  HCRYPTPROV = type NativeUInt;
  HCRYPTKEY = type NativeUInt;
  HCRYPTHASH = type NativeUInt;
  ALG_ID = Cardinal;
const
  PROV_RSA_FULL = 1;
  CRYPT_VERIFYCONTEXT = $F0000000;
  ALG_CLASS_HASH = 4 shl 13;
  ALG_TYPE_ANY = 0;
  ALG_SID_MD5 = 3;
  CALG_MD5 = ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD5;
  HP_HASHVAL = $0002;
function CryptAcquireContextW(
  out phProv: HCRYPTPROV;
  pszContainer: PWideChar;
  pszProvider: PWideChar;
  dwProvType: DWORD;
  dwFlags: DWORD
): BOOL; stdcall; external 'Advapi32.dll';
function CryptReleaseContext(
  hProv: HCRYPTPROV;
  dwFlags: DWORD
): BOOL; stdcall; external 'Advapi32.dll';
function CryptCreateHash(
  hProv: HCRYPTPROV;
  Algid: ALG_ID;
  hKey: HCRYPTKEY;
  dwFlags: DWORD;
  out phHash: HCRYPTHASH
): BOOL; stdcall; external 'Advapi32.dll';
function CryptDestroyHash(
  hHash: HCRYPTHASH
): BOOL; stdcall; external 'Advapi32.dll';
function CryptHashData(
  hHash: HCRYPTHASH;
  pbData: Pointer;
  dwDataLen: DWORD;
  dwFlags: DWORD
): BOOL; stdcall; external 'Advapi32.dll';
function CryptGetHashParam(
  hHash: HCRYPTHASH;
  dwParam: DWORD;
  pbData: Pointer;
  var pdwDataLen: DWORD;
  dwFlags: DWORD
): BOOL; stdcall; external 'Advapi32.dll';
function MD5Hash(Stream: TStream): TMD5Hash;
const
  BuffSize = 1024;
var
  hProv: HCRYPTPROV;
  hHash: HCRYPTHASH;
  Buff: array [0..BuffSize] of Byte;
  BytesLeft: Int64;
  BytesToRead: Integer;
  HashSize: DWORD;
begin
  Win32Check(CryptAcquireContextW(hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
  try
    Win32Check(CryptCreateHash(hProv, CALG_MD5, 0, 0, hHash));
    try
      BytesLeft := Stream.Size-Stream.Position;
      while BytesLeft>0 do begin
        BytesToRead := Min(BytesLeft, BuffSize);
        Stream.ReadBuffer(Buff, BytesToRead);
        Win32Check(CryptHashData(hHash, @Buff, BytesToRead, 0));
        dec(BytesLeft, BytesToRead);
      end;
      HashSize := SizeOf(Result);
      Win32Check(CryptGetHashParam(hHash, HP_HASHVAL, @Result, HashSize, 0));
    finally
      Win32Check(CryptDestroyHash(hHash));
    end;
  finally
    Win32Check(CryptReleaseContext(hProv, 0));
  end;
end;
function MD5Hash(const Str: RawByteString): TMD5Hash;
var
  Stream: TStringStream;
begin
  Stream := TStringStream.Create(Str);
  try
    Result := MD5Hash(Stream);
  finally
    Stream.Free;
  end;
end;
function MD5Hash(const Bytes: TBytes): TMD5Hash;
var
  Stream: TBytesStream;
begin
  Stream := TBytesStream.Create(Bytes);
  try
    Result := MD5Hash(Stream);
  finally
    Stream.Free;
  end;
end;
function MD5ToString(const Hash: TMD5Hash): string;
begin
  SetLength(Result, SizeOf(Hash)*2);
  BinToHex(Pointer(@Hash)^, PChar(Result), SizeOf(Hash));
end;
end.