// File: dguglielmi[P]dlan-linux-software/common/hptools.cpp
// Function: HomePlugTools::KeyFromPassword(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned char*)
void HomePlugTools::KeyFromPassword(
  const std::string& strPassword,
  unsigned char cKEY[8])
{
  std::string strSaltedPassword = strPassword + std::string("\x08\x85\x6D\xAF\x7C\xF5\x81\x85", 8);
  
  md5_state md5;
  unsigned char digest[16];
  md5_init(&md5);
  md5_process(&md5, (const unsigned char*)strSaltedPassword.data(), strSaltedPassword.size());
  md5_done(&md5, digest);

  for(int i = 2; i <= 1000; i++)
  {
    md5_init(&md5);
    md5_process(&md5, digest, 16);
    md5_done(&md5, digest);
  }

  memcpy(cKEY, digest, 8);

  for(int i = 0; i < 8; i++)
  {
    int iOneBits = 0;

    for(int j = 0x02; j != 0x00; j <<= 1)
      if(j & cKEY[i])
        iOneBits++;

    if((iOneBits & 0x01))
      cKEY[i] &= 0xFE;
    else
      cKEY[i] |= 0x01;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x100(%rbp)
leaq -0x51(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x5540
movq -0xf8(%rbp), %rcx
leaq 0xe905(%rip), %rsi      # 0x386a1
leaq -0x50(%rbp), %rdi
movl $0x8, %edx
callq 0x53b0
jmp 0x29dac
movq -0x100(%rbp), %rsi
leaq -0x30(%rbp), %rdi
leaq -0x50(%rbp), %rdx
callq 0x32510
jmp 0x29dc2
leaq -0x50(%rbp), %rdi
callq 0x5240
leaq -0x51(%rbp), %rdi
callq 0x5380
leaq -0xc8(%rbp), %rdi
callq 0x29fe0
jmp 0x29de2
leaq -0x30(%rbp), %rdi
movq %rdi, -0x110(%rbp)
callq 0x5210
movq -0x110(%rbp), %rdi
movq %rax, -0x108(%rbp)
callq 0x5270
movq -0x108(%rbp), %rsi
movq %rax, %rdx
leaq -0xc8(%rbp), %rdi
callq 0x2a030
jmp 0x29e1d
leaq -0xc8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x2a170
jmp 0x29e32
movl $0x2, -0xe4(%rbp)
cmpl $0x3e8, -0xe4(%rbp)     # imm = 0x3E8
jg 0x29ee7
leaq -0xc8(%rbp), %rdi
callq 0x29fe0
jmp 0x29e5a
leaq -0xc8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
movl $0x10, %edx
callq 0x2a030
jmp 0x29e74
leaq -0xc8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x2a170
jmp 0x29e89
jmp 0x29e8b
movl -0xe4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe4(%rbp)
jmp 0x29e3c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x29ebf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x5240
leaq -0x51(%rbp), %rdi
callq 0x5380
jmp 0x29fcb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x5240
jmp 0x29fcb
movq -0x10(%rbp), %rax
movq -0xe0(%rbp), %rcx
movq %rcx, (%rax)
movl $0x0, -0xe8(%rbp)
cmpl $0x8, -0xe8(%rbp)
jge 0x29fb9
movl $0x0, -0xec(%rbp)
movl $0x2, -0xf0(%rbp)
cmpl $0x0, -0xf0(%rbp)
je 0x29f66
movl -0xf0(%rbp), %eax
movq -0x10(%rbp), %rcx
movslq -0xe8(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x29f54
movl -0xec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xec(%rbp)
jmp 0x29f56
movl -0xf0(%rbp), %eax
shll %eax
movl %eax, -0xf0(%rbp)
jmp 0x29f20
movl -0xec(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x29f8e
movq -0x10(%rbp), %rax
movslq -0xe8(%rbp), %rcx
movzbl (%rax,%rcx), %edx
andl $0xfe, %edx
movb %dl, (%rax,%rcx)
jmp 0x29fa3
movq -0x10(%rbp), %rax
movslq -0xe8(%rbp), %rcx
movzbl (%rax,%rcx), %edx
orl $0x1, %edx
movb %dl, (%rax,%rcx)
jmp 0x29fa5
movl -0xe8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe8(%rbp)
jmp 0x29eff
leaq -0x30(%rbp), %rdi
callq 0x5240
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x5530
nopw %cs:(%rax,%rax)