static int sqlcipher_ltc_hmac(void *ctx, int algorithm, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
  int rc, hash_idx;
  hmac_state hmac;
  unsigned long outlen;
  switch(algorithm) {
    case SQLCIPHER_HMAC_SHA1:
      hash_idx = find_hash("sha1");
      break;
    case SQLCIPHER_HMAC_SHA256:
      hash_idx = find_hash("sha256");
      break;
    case SQLCIPHER_HMAC_SHA512:
      hash_idx = find_hash("sha512");
      break;
    default:
      return SQLITE_ERROR;
  }

  if(hash_idx < 0) return SQLITE_ERROR;
  outlen = hash_descriptor[hash_idx].hashsize;

  if(in == NULL) return SQLITE_ERROR;
  if((rc = hmac_init(&hmac, hash_idx, hmac_key, key_sz)) != CRYPT_OK) return SQLITE_ERROR;
  if((rc = hmac_process(&hmac, in, in_sz)) != CRYPT_OK) return SQLITE_ERROR;
  if(in2 != NULL && (rc = hmac_process(&hmac, in2, in2_sz)) != CRYPT_OK) return SQLITE_ERROR;
  if((rc = hmac_done(&hmac, out, &outlen)) != CRYPT_OK) return SQLITE_ERROR;
  return SQLITE_OK;
}
Beispiel #2
0
/**
  HMAC a file
  @param hash     The index of the hash you wish to use
  @param fname    The name of the file you wish to HMAC
  @param key      The secret key
  @param keylen   The length of the secret key
  @param out      [out] The HMAC authentication tag
  @param outlen   [in/out]  The max size and resulting size of the authentication tag
  @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
*/
int hmac_file(int hash, const char *fname, 
              const unsigned char *key, unsigned long keylen, 
                    unsigned char *out, unsigned long *outlen)
{
#ifdef LTC_NO_FILE
    return CRYPT_NOP;
#else
   hmac_state hmac;
   FILE *in;
   unsigned char buf[512];
   size_t x;
   int err;

   LTC_ARGCHK(fname  != NULL);
   LTC_ARGCHK(key    != NULL);
   LTC_ARGCHK(out    != NULL);
   LTC_ARGCHK(outlen != NULL);
   
   if((err = hash_is_valid(hash)) != CRYPT_OK) {
       return err;
   }

   if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
       return err;
   }

   in = fopen(fname, "rb");
   if (in == NULL) {
      return CRYPT_FILE_NOTFOUND;
   }

   /* process the file contents */
   do {
      x = fread(buf, 1, sizeof(buf), in);
      if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) {
         /* we don't trap this error since we're already returning an error! */
         fclose(in);
         return err;
      }
   } while (x == sizeof(buf));

   if (fclose(in) != 0) {
      return CRYPT_ERROR;
   }

   /* get final hmac */
   if ((err = hmac_done(&hmac, out, outlen)) != CRYPT_OK) {
      return err;
   }

#ifdef LTC_CLEAN_STACK
   /* clear memory */
   zeromem(buf, sizeof(buf));
#endif   
   return CRYPT_OK;
#endif
}
/**
   HMAC multiple blocks of memory to produce the authentication tag
   @param hash      The index of the hash to use
   @param key       The secret key
   @param keylen    The length of the secret key (octets)
   @param out       [out] Destination of the authentication tag
   @param outlen    [in/out] Max size and resulting size of authentication tag
   @param in        The data to HMAC
   @param inlen     The length of the data to HMAC (octets)
   @param ...       tuples of (data,len) pairs to HMAC, terminated with a (NULL,x) (x=don't care)
   @return CRYPT_OK if successful
*/
int hmac_memory_multi(int hash,
                const unsigned char *key,  unsigned long keylen,
                      unsigned char *out,  unsigned long *outlen,
                const unsigned char *in,   unsigned long inlen, ...)

{
    hmac_state          *hmac;
    int                  err;
    va_list              args;
    const unsigned char *curptr;
    unsigned long        curlen;

    LTC_ARGCHK(key    != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(outlen != NULL);

    /* allocate ram for hmac state */
    hmac = XMALLOC(sizeof(hmac_state));
    if (hmac == NULL) {
       return CRYPT_MEM;
    }

    if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    va_start(args, inlen);
    curptr = in;
    curlen = inlen;
    for (;;) {
       /* process buf */
       if ((err = hmac_process(hmac, curptr, curlen)) != CRYPT_OK) {
          goto LBL_ERR;
       }
       /* step to next */
       curptr = va_arg(args, const unsigned char*);
       if (curptr == NULL) {
          break;
       }
       curlen = va_arg(args, unsigned long);
    }
    if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) {
       goto LBL_ERR;
    }
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(hmac, sizeof(hmac_state));
#endif
   XFREE(hmac);
   va_end(args);
   return err;
}
static int sqlcipher_ltc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
  int rc, hash_idx;
  hmac_state hmac;
  unsigned long outlen = key_sz;

  hash_idx = find_hash("sha1");
  if((rc = hmac_init(&hmac, hash_idx, hmac_key, key_sz)) != CRYPT_OK) return SQLITE_ERROR;
  if((rc = hmac_process(&hmac, in, in_sz)) != CRYPT_OK) return SQLITE_ERROR;
  if((rc = hmac_process(&hmac, in2, in2_sz)) != CRYPT_OK) return SQLITE_ERROR;
  if((rc = hmac_done(&hmac, out, &outlen)) != CRYPT_OK) return SQLITE_ERROR;
  return SQLITE_OK;
}
Beispiel #5
0
void Encrypt(PK0304* le, AE_EXTRA* ae, char* password)
{
 char *salt, *key1, *key2, *check, digest[40];
 u32 key_len = KeySize*2 + 2;
 u32 dig_len = 40;

 salt = BUF;
 key1 = salt+SaltSize;
 key2 = key1+KeySize;
 check = key2+KeySize;

 /* Gets a random salt (8-16 byte) */
 sprng_read(salt, SaltSize, 0);

 /* Generates 2 keys for AES and HMAC, plus 2-byte password verification value */
 if (pkcs_5_alg2(password, strlen(password), salt, SaltSize, 1000, 0, key1, &key_len) != CRYPT_OK)
  Z_ERROR("Failed to derive encryption keys");

// dump("salt", salt, SaltSize);
// dump("key", key1, KeySize);

 if (ctr_start(0, IV, key1, KeySize, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) != CRYPT_OK)
  Z_ERROR("Failed to setup AES CTR encoder");
#ifdef GLADMAN_HMAC
 hmac_sha1_begin(&hmac);
 hmac_sha1_key(key2, KeySize, &hmac);
#else
 if (hmac_init(&hmac, 0, key2, KeySize) != CRYPT_OK)
  Z_ERROR("Failed to setup HMAC-SHA1");
#endif
 if (AE2) le->Crc32 = 0;
 le->Flag |= 1;
 le->CompMethod = 99;
 le->ExtraLen += 11;
 le->CompSize += SaltSize + 12; /* variable salt, fixed password check and hmac */

 safeWrite(ZOUT, le, sizeof(PK0304));
 fileCopy(ZOUT, ZIN, le->NameLen+le->ExtraLen-11);
 safeWrite(ZOUT, ae, 11);
 safeWrite(ZOUT, salt, SaltSize);
 safeWrite(ZOUT, check, 2);
 /* encrypt contents */
 fileFilter(ZOUT, ZIN, le->CompSize-SaltSize-12);
#ifdef GLADMAN_HMAC
 hmac_sha1_end(digest, dig_len, &hmac);
#else
 if (hmac_done(&hmac, digest, &dig_len) != CRYPT_OK)
  Z_ERROR("Failed to computate HMAC");
#endif
 safeWrite(ZOUT, digest, 10);
 ctr_done(&ctr);
}
/**
   HMAC a block of memory to produce the authentication tag
   @param hash      The index of the hash to use 
   @param key       The secret key 
   @param keylen    The length of the secret key (octets)
   @param in        The data to HMAC
   @param inlen     The length of the data to HMAC (octets)
   @param out       [out] Destination of the authentication tag
   @param outlen    [in/out] Max size and resulting size of authentication tag
   @return CRYPT_OK if successful
*/
int hmac_memory(int hash, 
                const unsigned char *key,  unsigned long keylen,
                const unsigned char *in,   unsigned long inlen, 
                      unsigned char *out,  unsigned long *outlen)
{
    hmac_state *hmac;
    int         err;

    LTC_ARGCHK(key    != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL); 
    LTC_ARGCHK(outlen != NULL);

    /* make sure hash descriptor is valid */
    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
       return err;
    }

    /* is there a descriptor? */
    if (hash_descriptor[hash].hmac_block != NULL) {
        return hash_descriptor[hash].hmac_block(key, keylen, in, inlen, out, outlen);
    }

    /* nope, so call the hmac functions */
    /* allocate ram for hmac state */
    hmac = XMALLOC(sizeof(hmac_state));
    if (hmac == NULL) {
       return CRYPT_MEM;
    }

    if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) {
       goto LBL_ERR;
    }

   err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(hmac, sizeof(hmac_state));
#endif

   XFREE(hmac);
   return err;   
}
Beispiel #7
0
/* Checks the mac in hashbuf, for the data in readbuf.
 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
static int checkmac(buffer* macbuf, buffer* sourcebuf) {

	unsigned char macsize;
	hmac_state hmac;
	unsigned char tempbuf[MAX_MAC_LEN];
	unsigned long hashsize;
	int len;

	macsize = ses.keys->recv_algo_mac->hashsize;

	if (macsize == 0) {
		return DROPBEAR_SUCCESS;
	}

	/* calculate the mac */
	if (hmac_init(&hmac, 
				find_hash(ses.keys->recv_algo_mac->hashdesc->name), 
				ses.keys->recvmackey, 
				ses.keys->recv_algo_mac->keysize) 
				!= CRYPT_OK) {
		dropbear_exit("HMAC error");
	}
	
	/* sequence number */
	STORE32H(ses.recvseq, tempbuf);
	if (hmac_process(&hmac, tempbuf, 4) != CRYPT_OK) {
		dropbear_exit("HMAC error");
	}

	buf_setpos(sourcebuf, 0);
	len = sourcebuf->len;
	if (hmac_process(&hmac, buf_getptr(sourcebuf, len), len) != CRYPT_OK) {
		dropbear_exit("HMAC error");
	}

	hashsize = sizeof(tempbuf);
	if (hmac_done(&hmac, tempbuf, &hashsize) != CRYPT_OK) {
		dropbear_exit("HMAC error");
	}

	/* compare the hash */
	if (memcmp(tempbuf, buf_getptr(macbuf, macsize), macsize) != 0) {
		return DROPBEAR_FAILURE;
	} else {
		return DROPBEAR_SUCCESS;
	}
}
Beispiel #8
0
/* Create the packet mac, and append H(seqno|clearbuf) to the output */
static void writemac(buffer * outputbuffer, buffer * clearwritebuf) {

	int macsize;
	unsigned char seqbuf[4];
	unsigned long hashsize;
	hmac_state hmac;

	TRACE(("enter writemac"));

	macsize = ses.keys->trans_algo_mac->hashsize;

	if (macsize > 0) {
		/* calculate the mac */
		if (hmac_init(&hmac, 
					find_hash(ses.keys->trans_algo_mac->hashdesc->name), 
					ses.keys->transmackey, 
					ses.keys->trans_algo_mac->keysize) != CRYPT_OK) {
			dropbear_exit("HMAC error");
		}
	
		/* sequence number */
		STORE32H(ses.transseq, seqbuf);
		if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
			dropbear_exit("HMAC error");
		}
	
		/* the actual contents */
		buf_setpos(clearwritebuf, 0);
		if (hmac_process(&hmac, 
					buf_getptr(clearwritebuf, 
						clearwritebuf->len),
					clearwritebuf->len) != CRYPT_OK) {
			dropbear_exit("HMAC error");
		}
	
		hashsize = macsize;
		if (hmac_done(&hmac, buf_getwriteptr(outputbuffer, macsize), &hashsize) 
				!= CRYPT_OK) {
			dropbear_exit("HMAC error");
		}
		buf_incrwritepos(outputbuffer, macsize);
	}
	TRACE(("leave writemac"));
}
/**
   HMAC a block of memory to produce the authentication tag
   @param hash      The index of the hash to use 
   @param key       The secret key 
   @param keylen    The length of the secret key (octets)
   @param in        The data to HMAC
   @param inlen     The length of the data to HMAC (octets)
   @param out       [out] Destination of the authentication tag
   @param outlen    [in/out] Max size and resulting size of authentication tag
   @return CRYPT_OK if successful
*/
int hmac_memory(int hash, 
                const unsigned char *key,  unsigned long keylen,
                const unsigned char *in,   unsigned long inlen, 
                      unsigned char *out,  unsigned long *outlen)
{
    hmac_state *hmac;
    int err;

    LTC_ARGCHK(key    != NULL);
    LTC_ARGCHK(in   != NULL);
    LTC_ARGCHK(out    != NULL); 
    LTC_ARGCHK(outlen != NULL);

    /* allocate ram for hmac state */
    hmac = XMALLOC(sizeof(hmac_state));
    if (hmac == NULL) {
       return CRYPT_MEM;
    }

    if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) {
       goto LBL_ERR;
    }

   err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(hmac, sizeof(hmac_state));
#endif

   XFREE(hmac);
   return err;   
}
Beispiel #10
0
int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, 
                const unsigned char *salt,     unsigned long salt_len,
                int iteration_count,           int hash_idx,
                unsigned char *out,            unsigned long *outlen)
{
   int err, itts;
   ulong32  blkno;
   unsigned long stored, left, x, y;
   unsigned char *buf[2];
   hmac_state    *hmac;

   LTC_ARGCHK(password != NULL);
   LTC_ARGCHK(salt     != NULL);
   LTC_ARGCHK(out      != NULL);
   LTC_ARGCHK(outlen   != NULL);

   /* test hash IDX */
   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
      return err;
   }

   buf[0] = XMALLOC(MAXBLOCKSIZE * 2);
   hmac   = XMALLOC(sizeof(hmac_state));
   if (hmac == NULL || buf[0] == NULL) {
      if (hmac != NULL) {
         XFREE(hmac);
      }
      if (buf[0] != NULL) {
         XFREE(buf[0]);
      }
      return CRYPT_MEM;
   }
   /* buf[1] points to the second block of MAXBLOCKSIZE bytes */
   buf[1] = buf[0] + MAXBLOCKSIZE;

   left   = *outlen;
   blkno  = 1;
   stored = 0;
   while (left != 0) {
       /* process block number blkno */
       zeromem(buf[0], MAXBLOCKSIZE*2);
       
       /* store current block number and increment for next pass */
       STORE32H(blkno, buf[1]);
       ++blkno;

       /* get PRF(P, S||int(blkno)) */
       if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) { 
          goto LBL_ERR;
       }
       if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {
          goto LBL_ERR;
       }
       if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {
          goto LBL_ERR;
       }
       x = MAXBLOCKSIZE;
       if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {
          goto LBL_ERR;
       }

       /* now compute repeated and XOR it in buf[1] */
       XMEMCPY(buf[1], buf[0], x);
       for (itts = 1; itts < iteration_count; ++itts) {
           if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {
              goto LBL_ERR;
           }
           for (y = 0; y < x; y++) {
               buf[1][y] ^= buf[0][y];
           }
       }

       /* now emit upto x bytes of buf[1] to output */
       for (y = 0; y < x && left != 0; ++y) {
           out[stored++] = buf[1][y];
           --left;
       }
   }
   *outlen = stored;

   err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(buf[0], MAXBLOCKSIZE*2);
   zeromem(hmac, sizeof(hmac_state));
#endif

   XFREE(hmac);
   XFREE(buf[0]);

   return err;
}
Beispiel #11
0
void Decrypt(PK0304 *le, char *password)
{
 char *salt, *key1, *key2, *check, digest[40];
 u32 key_len, dig_len = 40, start, xlen;
 AE_EXTRA ae;

 start = ftell(ZIN);
 /* Searches for AE-1 header */
 fseek(ZIN, le->NameLen, SEEK_CUR);
 for(xlen=le->ExtraLen; xlen;)
 {
  safeRead(&ae, ZIN, 4);
  xlen -= (4 + ae.Size);
  if (ae.Sig == 0x9901)
  {
   safeRead(&ae.Version, ZIN, 7);
   continue;
  }
  fseek(ZIN, ae.Size, SEEK_CUR);
 }
 if (ae.Sig != 0x9901)
  Z_ERROR("Fatal! Can't find AE extra header!");
 if (ae.Strength < 1 || ae.Strength > 3)
  Z_ERROR("Bad encryption strength");
 SaltSize = KS[ae.Strength].Salt;
 KeySize = KS[ae.Strength].Key;

 salt = BUF;
 key1 = salt+SaltSize;
 key2 = key1+KeySize;
 check = key2+KeySize;
 key_len = KeySize*2+2;

 /* Loads salt and password check value, and regenerates original crypto material */
 fseek(ZIN, start+le->NameLen+le->ExtraLen, SEEK_SET);
 safeRead(salt, ZIN, SaltSize);
 safeRead(check+2, ZIN, 2);
point1:
 if (pkcs_5_alg2(password, strlen(password), salt, SaltSize, 1000, 0, key1, &key_len) != CRYPT_OK)
  Z_ERROR("Failed to derive encryption keys");
 if (memcmp(check, check+2, 2))
 {
  printf("\nCan't decrypt data: try another password.\nNew password: "******"\n");
  goto point1;
 }
 if (ctr_start(0, IV, key1, KeySize, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) != CRYPT_OK)
  Z_ERROR("Failed to setup AES CTR decoder");
#ifdef GLADMAN_HMAC
 hmac_sha1_begin(&hmac);
 hmac_sha1_key(key2, KeySize, &hmac);
#else
 if (hmac_init(&hmac, 0, key2, KeySize) != CRYPT_OK)
  Z_ERROR("Failed to setup HMAC-SHA1");
#endif
 /* Adjusts local header */
 le->Flag ^= 1;
 le->CompMethod = ae.CompMethod;
 le->ExtraLen -= 11;
 le->CompSize -= (SaltSize + 12);
 /* Writes local header and copies extra, except 0x9901 */
 safeWrite(ZOUT, le, sizeof(PK0304));
 fseek(ZIN, start, SEEK_SET);
 fileCopy(ZOUT, ZIN, le->NameLen);
 for(xlen=le->ExtraLen+11; xlen;)
 {
  safeRead(&ae, ZIN, 4);
  xlen -= (4 + ae.Size);
  if (ae.Sig == 0x9901)
  {
   safeRead(&ae.Version, ZIN, 7);
   continue;
  }
  safeWrite(ZOUT, &ae, 4);
  fileCopy(ZOUT, ZIN, ae.Size);
 }
 fseek(ZIN, SaltSize+2, SEEK_CUR);

 fileFilter(ZOUT, ZIN, le->CompSize);

#ifdef GLADMAN_HMAC
 hmac_sha1_end(digest, dig_len, &hmac);
#else
 if (hmac_done(&hmac, digest, &dig_len) != CRYPT_OK)
  Z_ERROR("Failed to computate HMAC");
#endif
 /* Retrieves and checks HMACs */
 safeRead(digest+10, ZIN, 10);
 if (memcmp(digest, digest+10, 10))
  printf(" authentication failed, contents were lost!");
 ctr_done(&ctr);
}