#include <stdlib.h>
#include <unistd.h>

#include "libpgp5.h"

/* replace this if you have better */
char *(*getpphrase) (const char *) = getpass;
/*------------------------------------*/
/* string to key and initialize conventional encryption */
int getcfbkey(unsigned char **bp, unsigned char *passph, void **ccfb)
{
  unsigned int i = 0, j, k = 0, ca, ha, sa, tag;
  unsigned char hbuf[256], hkobuf[256];

  tag = *(*bp)++;               /* application */
  if (tag == 0)
    return 0;
  if (!passph || !passph[0])
    passph = (*getpphrase) ("Passphrase:");

  if (tag == 1)
    ca = 1, ha = 1, sa = 0;
  else
    ca = *(*bp)++, sa = *(*bp)++, ha = *(*bp)++;  /* crypto, salt, hash type */

  if (sa & 1) {
    memcpy(hbuf, *bp, 8);       /* salt */
    memcpy(&hbuf[8], passph, strlen(passph));
    *bp += 8;
    k = 8 + strlen(passph);
    i = k;
  }
  switch (sa) {
  case 3:
    i = *(*bp)++;               /* postfix - hash size */
    j = i >> 4;
    i = (i & 15) + 16;
    i <<= j + 6;
    break;
  case 0:
    memcpy(hbuf, passph, strlen(passph));
    i = strlen(passph);
    k = i;
    break;
  case 1:
    break;
  default:
    return -1;
  }

  if ((sa == 3) && i < strlen(passph) + 8)
    i = strlen(passph) + 8;

  keyhash(ha, i, k, cnvkeysiz(ca), hbuf, hkobuf);

  if (tag == 0xff || tag == 1) {
    memcpy(hbuf, *bp, 8);
    *bp += 8;
  } else
    memset(hbuf, 0, 8);

  *ccfb = cfbinit(hkobuf, hbuf, ca, 0);
  return tag;
}
