int main(){ unsigned char m[64]; unsigned char t[64]; unsigned char k[32]; unsigned char c[64]; unsigned char n[64]; for(int i=0; i<64; i++){ m[i]=0; t[i]=0; c[i]=0; } for(int i=0; i<32; i++){ k[i]=0; } strcpy(m, "Test"); strcpy(t, "Try"); strcpy(k, "Me"); encrypt_block(c, m, k,t); for(int i=0; i<64; i++){ printf("%.2x", c[i]); } printf("\n"); decrypt_block(n, c, k, t); if(memcmp(n, m, 64)){ printf("Failure!\n"); } else { printf("Success!\n"); } return 0; }
char* serpent_decrypt(uint32_t key[KEY_LENGTH], char* input, int test) { char* output; output = (char*) malloc(sizeof(char)); output[0] = '\0'; int done = F; uint32_t round_keys[NUM_ROUND_KEYS][ROUND_KEY_LENGTH]; uint32_t current_block[BLOCK_LENGTH]; uint32_t past_block[BLOCK_LENGTH]; uint32_t iv[BLOCK_LENGTH]; char** input_ptr = &input; key_schedule(round_keys, key); if (!test) { read_iv(input_ptr, iv); /* If test there isn't an IV */ } memcpy(past_block, iv, BLOCK_LENGTH * BYTE_CHUNK_SIZE); while (!done) { done = decrypt_read_block(input_ptr, current_block); decrypt_block(round_keys, current_block, past_block, output, test); // the function sets current_block from this call to past_block for next } return output; }
void DecryptCBC::decrypt(const void* src, void* dst, size_t len) { assert(len % 16 == 0); for (unsigned int i = 0; i < len; i += 16) { decrypt_block((uint8_t*)src + i, (uint8_t*)dst + i); } }
static const char* selftest(void) { BLOWFISH_context c; byte plain[] = "BLOWFISH"; byte buffer[8]; static const byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; static const byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 }; static const byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 }; const char *r; bf_setkey( (void *) &c, (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 ); encrypt_block( (void *) &c, buffer, plain ); if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) return "Blowfish selftest failed (1)."; decrypt_block( (void *) &c, buffer, buffer ); if( memcmp( buffer, plain, 8 ) ) return "Blowfish selftest failed (2)."; bf_setkey( (void *) &c, key3, 8 ); encrypt_block( (void *) &c, buffer, plain3 ); if( memcmp( buffer, cipher3, 8 ) ) return "Blowfish selftest failed (3)."; decrypt_block( (void *) &c, buffer, buffer ); if( memcmp( buffer, plain3, 8 ) ) return "Blowfish selftest failed (4)."; if ( (r = selftest_cbc ()) ) return r; if ( (r = selftest_cfb ()) ) return r; if ( (r = selftest_ctr ()) ) return r; return NULL; }
static bool validate_cert(unsigned char dest[128], const unsigned char *src, const unsigned char mod[128]) { unsigned char buf[128]; if (!decrypt_block(buf, &src[8], 210 - 8, mod)) return false; memcpy(&dest[0], &buf[36], 71); memcpy(&dest[71], &src[131 + 8], 57); return true; }
static bool signature() { return true; int chk = 1; FILE *fp; fp = fopen ( eEnv::resolve("${sysconfdir}/stb/info/model").c_str(), "r"); if (fp) { char line[256]; int n; fgets(line, sizeof(line), fp); if ((n = strlen(line)) && line[n - 1] == '\n') line[n - 1] = '\0'; fclose(fp); if (strstr(line,"dm7025")) chk = 0; } if (chk) { eTPM tpm; unsigned char rnd[CLEN]; /* read random bytes */ if (!read_random(rnd, CLEN)) return 1; unsigned char level2_mod[128]; unsigned char level3_mod[128]; unsigned char buf[128]; std::string challenge((char*)rnd, CLEN); std::string response = tpm.challenge(challenge); unsigned int len = response.size(); unsigned char val[len]; if ( len != 128 ) return false; memcpy(val, response.c_str(), len); std::string cert = tpm.getCert(eTPM::TPMD_DT_LEVEL2_CERT); if ( cert.size() != 210 || !validate_cert(level2_mod, (const unsigned char*) cert.c_str(), tpm_root_mod)) return false; cert = tpm.getCert(eTPM::TPMD_DT_LEVEL3_CERT); if ( cert.size() != 210 || !validate_cert(level3_mod, (const unsigned char*) cert.c_str(), level2_mod)) return false; if (!decrypt_block(buf, val, 128, level3_mod)) return false; if (memcmp(&buf[80], rnd, CLEN)) return false; return true; } else return true; }
int SL_Crypto_AES::decrypt(const unsigned char *input, unsigned int input_len, unsigned char *out, unsigned int out_len) { if (out_len < input_len) { return -1; } unsigned char *input_pos = (unsigned char *)(input + 1); unsigned char *out_pos = out; unsigned int block_count = input_len/block_size_; for (unsigned int i=0; i<block_count; ++i) { decrypt_block(input_pos, out_pos); input_pos += block_size_; out_pos += block_size_; } return (input_len-input[0]-1); }
/** * Interoperability test. * * data must point at an array of two driver structures. Data will be encrypted * with the first driver, and decrypted with the second. * * If the two drivers interoperate, the test passes. */ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t **drivers, const apr_crypto_block_key_type_e type, const apr_crypto_block_key_mode_e mode, int doPad, const unsigned char *in, apr_size_t inlen, const char *description) { const apr_crypto_driver_t *driver1 = drivers[0]; const apr_crypto_driver_t *driver2 = drivers[1]; apr_crypto_t *f1 = NULL; apr_crypto_t *f2 = NULL; const apr_crypto_key_t *key1 = NULL; const apr_crypto_key_t *key2 = NULL; unsigned char *cipherText = NULL; apr_size_t cipherTextLen = 0; unsigned char *plainText = NULL; apr_size_t plainTextLen = 0; const unsigned char *iv = NULL; apr_size_t blockSize = 0; f1 = make(tc, pool, driver1); f2 = make(tc, pool, driver2); key1 = passphrase(tc, pool, driver1, f1, type, mode, doPad, description); key2 = passphrase(tc, pool, driver2, f2, type, mode, doPad, description); cipherText = encrypt_block(tc, pool, driver1, f1, key1, in, inlen, &cipherText, &cipherTextLen, &iv, &blockSize, description); plainText = decrypt_block(tc, pool, driver2, f2, key2, cipherText, cipherTextLen, &plainText, &plainTextLen, iv, &blockSize, description); if (cipherText && plainText) { if (memcmp(in, plainText, inlen)) { fprintf(stderr, "cross mismatch: %s %s/%s\n", description, apr_crypto_driver_name(driver1), apr_crypto_driver_name( driver2)); } ABTS_STR_EQUAL(tc, (char *)in, (char *)plainText); } }
// EDAT/SDAT decryption. // reset file to beginning of data before calling int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD_HEADER *npd, unsigned char* crypt_key, bool verbose) { const int total_blocks = (int)((edat->file_size + edat->block_size - 1) / edat->block_size); u64 size_left = (int)edat->file_size; std::unique_ptr<u8> data(new u8[edat->block_size]); for (int i = 0; i < total_blocks; i++) { in->seek(0); memset(data.get(), 0, edat->block_size); u64 res = decrypt_block(in, data.get(), edat, npd, crypt_key, i, total_blocks, size_left); if (res == -1) { LOG_ERROR(LOADER, "EDAT: Decrypt Block failed!"); return 1; } size_left -= res; out->write(data.get(), res); } return 0; }
u64 EDATADecrypter::ReadData(u64 pos, u8* data, u64 size) { if (pos > edatHeader.file_size) return 0; // now we need to offset things to account for the actual 'range' requested const u64 startOffset = pos % edatHeader.block_size; const u32 num_blocks = static_cast<u32>(std::ceil((startOffset + size) / (double)edatHeader.block_size)); const u64 bufSize = num_blocks*edatHeader.block_size; if (data_buf_size < (bufSize)) { data_buf.reset(new u8[bufSize]); data_buf_size = bufSize; } // find and decrypt block range covering pos + size const u32 starting_block = static_cast<u32>(pos / edatHeader.block_size); const u32 ending_block = std::min(starting_block + num_blocks, total_blocks); u64 writeOffset = 0; for (u32 i = starting_block; i < ending_block; ++i) { edata_file.seek(0); u64 res = decrypt_block(&edata_file, &data_buf[writeOffset], &edatHeader, &npdHeader, dec_key.data(), i, total_blocks, edatHeader.file_size); if (res == -1) { LOG_ERROR(LOADER, "Error Decrypting data"); return 0; } writeOffset += res; } const u64 bytesWrote = std::min<u64>(writeOffset - startOffset, size); memcpy(data, &data_buf[startOffset], bytesWrote); return bytesWrote; }
// Decrypts the input using AES-128 driven by tablefile in the ECB mode using key // as the decryption key (16-byte long and in hexstring format) void decrypt(char *key_chars, FILE *table, FILE *input) { unsigned char round_key[44][4] = { { 0 } }; unsigned char* init_key = (unsigned char*)calloc(1,16); unsigned char* cipher_block = (unsigned char*)calloc(1,16); unsigned char* plain_block = (unsigned char*)calloc(1,16); // Verify table if(!tablecheck(table)) { return; } // Check key length if(strlen(key_chars) != 32) { fprintf(stderr, "ERROR: key must consist of 32 characters, all hex values.\n"); return; } // Read raw key hexchars in and convert to bytes else { char temp_val[3]; for(int i=0; i<16; i++) { if(!is_hex_char(key_chars[i*2]) || !is_hex_char(key_chars[i*2+1])) { fprintf(stderr, "ERROR: all values in the polynomial must be hex values.\n"); return; } temp_val[0] = key_chars[i*2]; temp_val[1] = key_chars[i*2+1]; temp_val[2] = ' '; init_key[i] = strtol(temp_val, NULL, 16); } } // Perform key expansion and store result in round_key key_expansion(init_key, round_key, table); /* // Read first 16 bytes from input text if(fread(cipher_block, 1, 16, input) < 16) { fprintf(stderr, "ERROR: input file was less than 16 bytes long.\n"); return; }*/ // Encrypt everything from input in 16-byte block bool first = true; int size; while((size = fread(cipher_block, 1, 16, input))) { if((*cipher_block == '\n') && (size == 1)) continue; // Encrypt a single block using AES-128 decrypt_block(cipher_block, plain_block, round_key, table, first); // Print current cipher block values to output for(int i=0; i<16; i++) { printf("%c", plain_block[i]); } // Reset blocks for next iteration first = false; for(int i=0; i<16; i++) { plain_block[i] = 0x00; cipher_block[i] = 0x00; } } free(init_key); free(plain_block); free(cipher_block); // PSEUDO-CODE // - Same as AES-128 encrypt, except for a few minor changes: // - The S-box needs to be inverted before it can be used for substitution // - You use the inverse polynomial instead of the original for mix_columns // - During shift_rows, you shift each row to the right instead of the left // - The round keys are used in reverse order // - The order of core operations is also slightly different // - Inv Shift Columns // - Substitute Bytes (inverse S-box) // - Add Round Key // - Mix Columns (inverse polynomial) // EDIT: modified to decrypt entire input with AES-128. Prints state outputs to stderr on first block. }
int decrypt_final(struct poet_ctx *ctx, const uint8_t *ciphertext, uint64_t clen, const uint8_t tag[BLOCKLEN], uint8_t *plaintext) { #ifdef DEBUG int i; #endif uint64_t offset=0; block s; block tmp; block tmp2; int alpha; int beta; uint64_t len; while( clen > BLOCKLEN ) { decrypt_block(ctx, ciphertext+offset, plaintext+offset); clen -= BLOCKLEN; offset += BLOCKLEN; } /* Encrypt length of message */ ctx->mlen+=(clen*8); memset(s,0,BLOCKLEN); len = TO_LITTLE_ENDIAN_64(ctx->mlen); memcpy(s, &len, 8); AES_encrypt(s, s ,&(ctx->aes_enc)); /* Last ciphertext block must be padded if necesscary */ memcpy(tmp,ciphertext+offset,clen); memcpy(tmp+clen,tag,BLOCKLEN-clen); /* Process last block + tag generation */ BOTTOM_HASH; xor_block(tmp,s,tmp); xor_block(ctx->y, tmp,ctx->y); AES_decrypt(ctx->y, tmp, &(ctx->aes_dec)); TOP_HASH; xor_block(tmp2, tmp, ctx->x); xor_block(tmp2, s, tmp2); memcpy(ctx->x,tmp,BLOCKLEN); #ifdef DEBUG puts("S"); for(i=0;i<16;i++) printf("%02x ",s[i]); puts(""); puts("X"); for(i=0;i<16;i++) printf("%02x ",ctx->x[i]); puts(""); puts("Y"); for(i=0;i<16;i++) printf("%02x ",ctx->y[i]); puts(""); #endif /* Do tag splitting if needed */ memcpy(plaintext+offset,tmp2,clen); alpha = memcmp(tmp2+clen,ctx->tau,BLOCKLEN-clen); /* Generate tag */ TOP_HASH; xor_block(ctx->x, ctx->tau ,ctx->x); xor_block(ctx->x, ctx->tm ,ctx->x); AES_encrypt(ctx->x, tmp, &(ctx->aes_enc)); BOTTOM_HASH; xor_block(tmp, ctx->y, tmp); xor_block(tmp, ctx->tm, tmp); #ifdef DEBUG puts("tmp"); for(i=0;i<16;i++) printf("%02x ",tmp[i]); puts(""); puts("tag"); for(i=0;i<16;i++) printf("%02x ",tag[i]); puts(""); #endif beta = memcmp(tmp,tag+(BLOCKLEN-clen),clen); return alpha|beta; }
// ******************************************* // Public Function Implementation // ******************************************* int s3fs::Crypto::preadAES(int fd, char *buf, size_t buflen, off_t offset) { unsigned char readBlock[AES_BLOCK_SIZE]; unsigned char writeBlock[AES_BLOCK_SIZE]; unsigned char buffer[sizeof(char[buflen])]; size_t offsetIndex = offset % AES_BLOCK_SIZE; size_t readOffset = offset - offsetIndex; int bytesRead = 0; int byteIndex = 0; int padlen = 0; int filesize = 0; struct stat st; if(fstat(fd, &st) != 0) return 1; filesize = st.st_size; // FGPRINT("s3fs::Crypto Encrypted filesize %ld\n", filesize); // SYSLOGERR("s3fs::Crypto Encrypted filesize %ld", filesize); //Read the last cipher block to determine the true file size memset(readBlock, 0, AES_BLOCK_SIZE); memset(writeBlock, 0, AES_BLOCK_SIZE); bytesRead = pread(fd, readBlock, AES_BLOCK_SIZE, (filesize - AES_BLOCK_SIZE)); if(bytesRead > 0) { memset(writeBlock, 0, AES_BLOCK_SIZE); decrypt_block(readBlock, bytesRead, writeBlock); padlen = get_padding(writeBlock); // FGPRINT("s3fs::Crypto Encrypted padding length %d\n", padlen); filesize -= padlen; } if(buflen > filesize) buflen = filesize; memset(readBlock, 0, AES_BLOCK_SIZE); memset(writeBlock, 0, AES_BLOCK_SIZE); memset(buffer, 0, sizeof(buffer)); do { memset(readBlock, 0, AES_BLOCK_SIZE); bytesRead = pread(fd, readBlock, AES_BLOCK_SIZE, readOffset); if(bytesRead > 0) { memset(writeBlock, 0, AES_BLOCK_SIZE); decrypt_block(readBlock, bytesRead, writeBlock); readOffset += bytesRead; if(byteIndex == 0 ) { memcpy((buffer + byteIndex), (writeBlock + offsetIndex), (bytesRead - offsetIndex)); byteIndex += (bytesRead - offsetIndex); } else if((byteIndex + bytesRead) <= buflen) { memcpy((buffer + byteIndex), writeBlock, bytesRead); byteIndex += bytesRead; } else { memcpy((buffer + byteIndex), writeBlock, (bytesRead - ((byteIndex + bytesRead) - buflen))); byteIndex += ((byteIndex + bytesRead) - buflen); } } else { break; } } while(byteIndex <= buflen); if(byteIndex < buflen) { memcpy(buf, buffer, byteIndex); return byteIndex; } memcpy(buf, buffer, buflen); return buflen; }
/** * Process an incoming KEYINFO message. * Expected in response to a REGISTER when encryption is enabled. */ void handle_keyinfo(struct group_list_t *group, unsigned char *message, unsigned meslen, uint32_t src_id) { struct keyinfo_h *keyinfo_hdr; struct destkey *keylist; int i, keyidx, len, destkeycnt, unauth_keytype, unauth_keylen, unauth_ivlen; unsigned explen, declen; uint8_t decgroupmaster[MASTER_LEN], *prf_buf, *iv; uint64_t ivctr; keyinfo_hdr = (struct keyinfo_h *)message; keylist = (struct destkey *)(message + (keyinfo_hdr->hlen * 4)); if ((meslen < (keyinfo_hdr->hlen * 4U)) || ((keyinfo_hdr->hlen * 4U) < sizeof(struct keyinfo_h))) { glog1(group, "Rejecting KEYINFO from server: invalid message size"); return; } destkeycnt = (meslen - (keyinfo_hdr->hlen * 4)) / sizeof(struct destkey); // This duplicates uid_in_list, but here it's addressed in a struct array for (i = 0, keyidx = -1; (i < destkeycnt) && (keyidx == -1); i++) { if (uid == keylist[i].dest_id) { keyidx = i; } } // Don't use a cipher in an authentication mode to decrypt the group master unauth_keytype = unauth_key(group->keytype); get_key_info(unauth_keytype, &unauth_keylen, &unauth_ivlen); if (keyidx != -1) { glog2(group, "Received KEYINFO"); if (group->phase == PHASE_MIDGROUP) { // We already got the KEYINFO, so no need to reprocess. // Just resend the KEYINFO_ACK and reset the timeout send_keyinfo_ack(group); set_timeout(group, 0); return; } iv = safe_calloc(unauth_ivlen, 1); ivctr = ntohl(keyinfo_hdr->iv_ctr_lo); ivctr |= (uint64_t)ntohl(keyinfo_hdr->iv_ctr_hi) << 32; build_iv(iv, group->salt, unauth_ivlen, uftp_htonll(ivctr), src_id); if (!decrypt_block(unauth_keytype, iv, group->key, NULL, 0, keylist[keyidx].groupmaster, MASTER_LEN, decgroupmaster, &declen) || (declen != MASTER_LEN - 1)) { glog1(group, "Decrypt failed for group master"); send_abort(group, "Decrypt failed for group master"); free(iv); return; } free(iv); group->groupmaster[0] = group->version; memcpy(&group->groupmaster[1], decgroupmaster, declen); explen = group->keylen + SALT_LEN + group->hmaclen; prf_buf = safe_calloc(explen + group->hmaclen, 1); PRF(group->hashtype, explen, group->groupmaster, sizeof(group->groupmaster), "key expansion", group->rand1, sizeof(group->rand1), prf_buf, &len); memcpy(group->grouphmackey, prf_buf, group->hmaclen); memcpy(group->groupkey, prf_buf + group->hmaclen, group->keylen); memcpy(group->groupsalt, prf_buf + group->hmaclen + group->keylen, SALT_LEN); free(prf_buf); group->phase = PHASE_MIDGROUP; send_keyinfo_ack(group); set_timeout(group, 0); if (group->restart) { read_restart_file(group); } } }