#include "libopgp.h"
#include <rand.h>

/*------------------------------------*/
/* for secret keys only - inverse of getcfbkey */
int PGP_wrs2k(u8_t * obuf, const u8_t * passph, void **ccfb)
{
  u32_t i = 0, k, len;
  u8_t ivbuf[8], hbuf[256], hkobuf[256], tag;
  u8_t ha = 2, sa = 3, ca = 3, ic = 0x60;

  if (!passph || !*passph) {
    *obuf = 0;
    *ccfb = NULL;
    return 1;
  }
  tag = *obuf++;
  if (*obuf)                    /* user selected algorithms */
    ca = obuf[0], sa = obuf[1], ha = obuf[2], ic = obuf[3];
  else
    obuf[0] = ca, obuf[1] = sa, obuf[2] = ha;
  if (tag < 4)
    len = 1;
  else
    obuf += 3, len = 4;

  k = strlen(passph);

  if (sa && sa != 2) {
    RAND_bytes(hbuf, 8);        /* salt */
    memcpy(obuf, hbuf, 8);
    memcpy(&hbuf[8], passph, strlen(passph));
    obuf += 8, k += 8, len += 8;
  } else
    memcpy(hbuf, passph, strlen(passph));

  switch (sa) {
  case 3:
    *obuf++ = ic;
    len++;
    i = (16 + (ic & 15)) << ((ic >> 4) + 6);
    if (i < strlen(passph) + 8)
      i = strlen(passph) + 8;
    break;
  case 2:
    exit(-1);
  case 1:
  case 0:
    i = k;
    break;
  }

  MemSet(passph,strlen(passph),0);

  PGP_khash(ha, i, k, PGP_cksz(ca), hbuf, hkobuf);

  if (tag == 0xff || tag < 4) {
    RAND_bytes(ivbuf, 8);
    memcpy(obuf, ivbuf, 8);
    len += 8;
  } else
    memset(ivbuf, 0, 8);

  *ccfb = PGP_cini(hkobuf, ivbuf, ca, 1);
  memset(hkobuf, 0, 256);
  return len;                   /* LEN - currently fixed */
}
