static int _blobcrypt_decrypt_flush(blobcrypt_decrypt_state *state) { block_ad ad; unsigned long long plen; size_t clen; assert(state->buf_pos > (sizeof state->nonce) + (sizeof state->auth)); clen = state->buf_pos - (sizeof state->nonce); _u64_le_from_ull(ad.offset, state->offset); memcpy(ad.message_id, state->message_id, sizeof ad.message_id); if (block_decrypt(state->buf, &plen, state->buf, clen, (unsigned char *) (void *) &ad, sizeof ad, state->message_id, state->nonce, state->k) != 0) { sodium_memzero(ad.message_id, sizeof ad.message_id); _blobcrypt_decrypt_sinkhole(state); return -1; } sodium_memzero(ad.message_id, sizeof ad.message_id); assert(plen == clen - (sizeof state->auth)); if (state->write_cb(state->user_ptr, state->buf, (size_t) plen) != 0) { _blobcrypt_decrypt_sinkhole(state); return -1; } assert(state->total_len >= plen); assert(state->offset <= state->total_len - plen); state->buf_pos = 0U; state->offset += plen; return 0; }
/* Decrypt the given data. */ size_t rij_decrypt(unsigned char *in, size_t in_len, const char *key, const int key_len, unsigned char *out, int encryption_mode) { RIJNDAEL_context ctx; int i, pad_val, pad_err = 0; unsigned char *pad_s; unsigned char *ondx = out; if(in == NULL || key == NULL || out == NULL) return 0; rijndael_init(&ctx, key, key_len, in, encryption_mode); /* Remove the first block since it contains the salt (it was consumed * by the rijndael_init() function above). */ in_len -= RIJNDAEL_BLOCKSIZE; memmove(in, in+RIJNDAEL_BLOCKSIZE, in_len); block_decrypt(&ctx, in, in_len, out, ctx.iv); ondx += in_len; /* Find and remove padding. */ pad_val = *(ondx-1); if(pad_val >= 0 && pad_val <= RIJNDAEL_BLOCKSIZE) { pad_s = ondx - pad_val; for(i=0; i < (ondx-pad_s); i++) { if(*(pad_s+i) != pad_val) pad_err++; } if(pad_err == 0) ondx -= pad_val; } *ondx = '\0'; zero_buf((char *)ctx.key, RIJNDAEL_MAX_KEYSIZE); zero_buf((char *)ctx.iv, RIJNDAEL_BLOCKSIZE); zero_buf((char *)ctx.salt, SALT_LEN); return(ondx - out); }
int decrypt(char* message, const char* cipher, int length, private_key ku) { int msg_idx = 0; char buf[BLOCK_SIZE]; int i; mpz_t c; mpz_t m; mpz_init(c); mpz_init(m); memset(buf,0,BLOCK_SIZE); for(i = 0; i < (length / BLOCK_SIZE); i++) { int off; int j; // Pull block into mpz_t mpz_import(c, BLOCK_SIZE, 1, sizeof(char), 0, 0, cipher + i * BLOCK_SIZE); // Decrypt block block_decrypt(m, c, ku); // Calculate message write offset to take into account that we want to // pad with zeros in the front if the number we get back has fewer bits // than BLOCK_SIZE off = (BLOCK_SIZE - (mpz_sizeinbase(m, 2) + 8 - 1)/8); // See manual for mpz_export // Convert back to bitstream mpz_export(buf + off, NULL, 1, sizeof(char), 0, 0, m); // Now we just need to lop off top padding before memcpy-ing to message // We know the first 2 bytes are 0x00 and 0x02, so manually skip those // After that, increment forward till we see a zero byte for(j = 2; ((buf[j] != 0) && (j < BLOCK_SIZE)); j++); j++; // Skip the 00 byte /* Copy over the message part of the plaintext to the message return var */ memcpy(message + msg_idx, buf + j, BLOCK_SIZE - j); msg_idx += BLOCK_SIZE - j; } mpz_clear(c); mpz_clear(m); return msg_idx; }
int main (int argc, char **argv) { if (argc < 3) { printf("Invalid number of arguments: <key> [-e | -d] <input>\n"); exit(1); } int mode = (strcmp("-d", argv[2]) == 0) ? DECRYPT : ENCRYPT; unsigned char *input; int input_size = hex_decode(argv[3], &input); unsigned char *key; int key_size = hex_decode(argv[1], &key); printf("mode: %s\n", mode == DECRYPT ? "decrypt" : "encrypt"); block_state *block = malloc(sizeof(block_state)); if (block) memset(block, 0, sizeof(block_state)); unsigned char *e_buffer = malloc(input_size); unsigned char *d_buffer = malloc(input_size); block_init(block, key, key_size); block_encrypt(block, input, e_buffer); block_decrypt(block, e_buffer, d_buffer); printf("input buffer:\n"); print_buffer(input, input_size); printf("encrypted buffer:\n"); print_buffer(e_buffer, input_size); printf("decrypted buffer:\n"); print_buffer(d_buffer, input_size); printf("\n"); free(e_buffer); free(d_buffer); free(block); free(input); free(key); }
int main() { int i; mpz_t M; mpz_init(M); mpz_t C; mpz_init(C); mpz_t DC; mpz_init(DC); private_key ku; public_key kp; // Initialize public key mpz_init(kp.n); mpz_init(kp.e); // Initialize private key mpz_init(ku.n); mpz_init(ku.e); mpz_init(ku.d); mpz_init(ku.p); mpz_init(ku.q); generate_keys(&ku, &kp); printf("---------------Private Key-----------------"); printf("kp.n is [%s]\n", mpz_get_str(NULL, 16, kp.n)); printf("kp.e is [%s]\n", mpz_get_str(NULL, 16, kp.e)); printf("---------------Public Key------------------"); printf("ku.n is [%s]\n", mpz_get_str(NULL, 16, ku.n)); printf("ku.e is [%s]\n", mpz_get_str(NULL, 16, ku.e)); printf("ku.d is [%s]\n", mpz_get_str(NULL, 16, ku.d)); printf("ku.p is [%s]\n", mpz_get_str(NULL, 16, ku.p)); printf("ku.q is [%s]\n", mpz_get_str(NULL, 16, ku.q)); char buf[6*BLOCK_SIZE]; for(i = 0; i < 6*BLOCK_SIZE; i++) buf[i] = rand() % 0xFF; mpz_import(M, (6*BLOCK_SIZE), 1, sizeof(buf[0]), 0, 0, buf); printf("original is [%s]\n", mpz_get_str(NULL, 16, M)); block_encrypt(C, M, kp); printf("encrypted is [%s]\n", mpz_get_str(NULL, 16, C)); block_decrypt(DC, C, ku); printf("decrypted is [%s]\n", mpz_get_str(NULL, 16, DC)); return 0; }
static int decrypt(lua_State* pState) { AESObject* aes = (AESObject*)lua_touserdata(pState, 1); unsigned char *buffer, *str; unsigned char temp[BLOCK_SIZE]; int i, j, len; str = lua_tolstring(pState, 2, &len); if (len == 0) { lua_pushstring(pState, ""); return 1; } if ( (len % BLOCK_SIZE) !=0 && (aes->mode!=MODE_CFB)) { luaL_error(pState, "Input strings must be " "a multiple of %d in length", BLOCK_SIZE); return 0; } if (aes->mode == MODE_CFB && (len % (aes->segment_size/8) !=0)) { luaL_error(pState, "aInput strings must be a multiple of " "the segment size %d in length", aes->segment_size/8); return 0; } buffer = (char*)malloc(len); if (!buffer) { luaL_error(pState, "alloc memory error"); return 0; } switch(aes->mode) { case(MODE_ECB): for(i=0; i<len; i+=BLOCK_SIZE) { block_decrypt(&(aes->st), str+i, buffer+i); } break; case(MODE_CBC): for(i=0; i<len; i+=BLOCK_SIZE) { memcpy(aes->oldCipher, aes->IV, BLOCK_SIZE); block_decrypt(&(aes->st), str+i, temp); for(j=0; j<BLOCK_SIZE; j++) { buffer[i+j]=temp[j]^aes->IV[j]; aes->IV[j]=str[i+j]; } } break; case(MODE_CFB): for(i=0; i<len; i+=aes->segment_size/8) { block_encrypt(&(aes->st), aes->IV, temp); for (j=0; j<aes->segment_size/8; j++) { buffer[i+j] = str[i+j]^temp[j]; } if (aes->segment_size == BLOCK_SIZE * 8) { /* s == b: segment size is identical to the algorithm block size */ memcpy(aes->IV, str + i, BLOCK_SIZE); } else if ((aes->segment_size % 8) == 0) { int sz = aes->segment_size/8; memmove(aes->IV, aes->IV + sz, BLOCK_SIZE-sz); memcpy(aes->IV + BLOCK_SIZE - sz, str + i, sz); } else { /* segment_size is not a multiple of 8; currently this can't happen */ } } break; case (MODE_OFB): for(i=0; i<len; i+=BLOCK_SIZE) { block_encrypt(&(aes->st), aes->IV, temp); memcpy(aes->IV, temp, BLOCK_SIZE); for(j=0; j<BLOCK_SIZE; j++) { buffer[i+j] = str[i+j] ^ aes->IV[j]; } } break; default: free(buffer); luaL_error(pState, "not support mode"); return 0; } lua_pushlstring(pState, buffer, len); free(buffer); return 1; }
static int _blobcrypt_decrypt_read_header(blobcrypt_decrypt_state *state) { blob_header header; unsigned long long block_size_ull; unsigned long long total_len_advertised; size_t ad_len; size_t header_len; size_t header_secbytes; if (state->buf_pos < HEADER_PUBBYTES) { return 0; } if (memcmp(state->nonce, FILE_MAGIC, sizeof FILE_MAGIC - 1U) != 0) { return -1; } header_len = (size_t) _ul_from_u32_le(state->nonce + MAGIC_BYTES); if (header_len <= HEADER_PUBBYTES) { return -1; } if (header_len != HEADER_BYTES) { return -1; } if (state->buf_pos < header_len) { return 0; } assert(header_len == sizeof header); memcpy(&header, state->nonce, sizeof header); ad_len = _ul_from_u32_le(header.ad_len); if (header_len <= ad_len || ad_len < MAGIC_BYTES + 4U + 4U + block_NONCEBYTES) { return -1; } if (ad_len != HEADER_PUBBYTES) { return -1; } header_secbytes = header_len - ad_len; if (block_decrypt(header.message_id, NULL, header.message_id, header_secbytes, header.magic, ad_len, NULL, header.nonce, state->k) != 0) { return -1; } total_len_advertised = _ull_from_u64_le(header.total_len); if (state->total_len != blobcrypt_UNKNOWNSIZE && total_len_advertised != state->total_len) { sodium_memzero(&header, sizeof header); return -1; } state->total_len = _ull_from_u64_le(header.total_len); if (state->total_len >= ULLONG_MAX - (block_NONCEBYTES + block_ABYTES) - header_len) { sodium_memzero(&header, sizeof header); return -1; } block_size_ull = _ull_from_u64_le(header.block_size); if (block_size_ull <= block_NONCEBYTES + block_ABYTES || block_size_ull > block_MAXBYTES || block_size_ull >= SSIZE_MAX - (block_NONCEBYTES + block_ABYTES)) { sodium_memzero(&header, sizeof header); return -1; } if (block_size_ull > sizeof state->buf) { sodium_memzero(&header, sizeof header); return -1; } state->block_size = (size_t) block_size_ull; memcpy(state->message_id, header.message_id, sizeof state->message_id); sodium_memzero(&header, sizeof header); assert(state->buf_pos >= header_len); memmove(state->nonce, state->nonce + header_len, state->buf_pos - header_len); state->buf_pos -= header_len; state->state = 2; return 0; }