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

/* algorithms to password protect secret keys */
/* note: salt type is fixed at 3 */
int sechash = 2;
int secsalt = 3;
int seccrypt = 3;
int secitcnt = 0x60;            /* this is the folded floating version */
/* 0xPQ becomes (1024 + Q*64 ) * 2**P */

/*------------------------------------*/
/* for secret keys only - inverse of getcfbkey */
int putcfbkey(unsigned char *obuf, const unsigned char *passph,
              unsigned char tag, void **ccfb)
{
  unsigned int i = 0, k, len;
  unsigned char ivbuf[8];
  unsigned char hbuf[256], hkobuf[256];

  if (!passph) {
    *obuf++ = 0;
    *ccfb = NULL;
    return 1;
  }
  *obuf++ = tag, *obuf++ = seccrypt, *obuf++ = secsalt, *obuf++ = sechash;
  len = 4;                      /* mandatory bytes */

  k = strlen(passph);

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

  switch (secsalt) {
  case 3:
    *obuf++ = secitcnt;
    len++;
    i = (16 + (secitcnt & 15)) << ((secitcnt >> 4) + 6);
    break;
  case 2:
    exit(-1);
  case 1:
  case 0:
    i = k;
    break;
  }

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

  keyhash(sechash, i, k, cnvkeysiz(seccrypt), hbuf, hkobuf);

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

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