int memory_aeskey_is_erased(PASSWORD_ID id) { uint8_t mem_aeskey_erased[MEM_PAGE_LEN]; sha256_Raw((const uint8_t *)MEM_PAGE_ERASE, MEM_PAGE_LEN, mem_aeskey_erased); sha256_Raw(mem_aeskey_erased, MEM_PAGE_LEN, mem_aeskey_erased); if (memcmp(memory_read_aeskey(id), mem_aeskey_erased, 32)) { return STATUS_MEM_NOT_ERASED; } else { return STATUS_MEM_ERASED; } }
// Must free() returned value char *aes_cbc_b64_decrypt(const unsigned char *in, int inlen, int *decrypt_len, PASSWORD_ID id) { *decrypt_len = 0; if (!in || inlen == 0) { return NULL; } // Unbase64 int ub64len; unsigned char *ub64 = unbase64((char *)in, inlen, &ub64len); if (!ub64 || (ub64len % N_BLOCK) || ub64len < N_BLOCK) { free(ub64); return NULL; } // Set cipher key aes_context ctx[1]; memset(ctx, 0, sizeof(ctx)); aes_set_key(memory_read_aeskey(id), 32, ctx); unsigned char dec_pad[ub64len - N_BLOCK]; aes_cbc_decrypt(ub64 + N_BLOCK, dec_pad, ub64len / N_BLOCK - 1, ub64, ctx); memset(ub64, 0, ub64len); free(ub64); // Strip PKCS7 padding int padlen = dec_pad[ub64len - N_BLOCK - 1]; if (ub64len - N_BLOCK - padlen <= 0) { memset(dec_pad, 0, sizeof(dec_pad)); return NULL; } char *dec = malloc(ub64len - N_BLOCK - padlen + 1); // +1 for null termination if (!dec) { memset(dec_pad, 0, sizeof(dec_pad)); return NULL; } memcpy(dec, dec_pad, ub64len - N_BLOCK - padlen); dec[ub64len - N_BLOCK - padlen] = '\0'; *decrypt_len = ub64len - N_BLOCK - padlen + 1; memset(dec_pad, 0, sizeof(dec_pad)); return dec; }
// Must free() returned value (allocated inside base64() function) char *aes_cbc_b64_encrypt(const unsigned char *in, int inlen, int *out_b64len, PASSWORD_ID id) { int pads; int inpadlen = inlen + N_BLOCK - inlen % N_BLOCK; unsigned char inpad[inpadlen]; unsigned char enc[inpadlen]; unsigned char iv[N_BLOCK]; unsigned char enc_cat[inpadlen + N_BLOCK]; // concatenating [ iv0 | enc ] aes_context ctx[1]; // Set cipher key memset(ctx, 0, sizeof(ctx)); aes_set_key(memory_read_aeskey(id), 32, ctx); // PKCS7 padding memcpy(inpad, in, inlen); for (pads = 0; pads < N_BLOCK - inlen % N_BLOCK; pads++ ) { inpad[inlen + pads] = (N_BLOCK - inlen % N_BLOCK); } // Make a random initialization vector srand(time(NULL)); for (int i=0; i<N_BLOCK; i++) { iv[i]=rand(); } memcpy(enc_cat, iv, N_BLOCK); // CBC encrypt multiple blocks aes_cbc_encrypt( inpad, enc, inpadlen / N_BLOCK, iv, ctx ); memcpy(enc_cat + N_BLOCK, enc, inpadlen); // base64 encoding int b64len; char *b64; b64 = base64(enc_cat, inpadlen + N_BLOCK, &b64len); *out_b64len = b64len; memset(inpad, 0, inpadlen); return b64; }