uint8_t get_and_byte(shift_register_t sr) { uint8_t block1; uint8_t block2; block1 = get_block_at(1, sr); block2 = get_block_at(2, sr); return (block1 & block2); }
uint8_t get_next_key(trivium_keystream *tks) { /* Each shift register will produce a byte * * output, which is fed into a) the overall * * output byte, and b) into the next register * * (along with a feedback byte. */ uint8_t A_out, B_out, C_out; uint8_t feedback_A, feedback_B, feedback_C; feedback_A = get_block_at(24, *tks->srA); feedback_B = get_block_at(6, *tks->srB); feedback_C = get_block_at(24, *tks->srC); uint8_t feedforward_A, feedforward_B, feedforward_C; feedforward_A = get_block_at(27, *tks->srA); feedforward_B = get_block_at(15, *tks->srB); feedforward_C = get_block_at(45, *tks->srC); /* There are some values we need to save * before we shift. */ uint8_t and_byte_A, and_byte_B, and_byte_C; and_byte_A = get_and_byte(*tks->srA); and_byte_B = get_and_byte(*tks->srB); and_byte_C = get_and_byte(*tks->srC); /* Do the shift and save the output bytes */ uint8_t shift_byte_A, shift_byte_B, shift_byte_C; shift_byte_A = block_shift(tks->srA); shift_byte_B = block_shift(tks->srB); shift_byte_C = block_shift(tks->srC); /* Now compute the output of each shift register */ A_out = (shift_byte_A ^ and_byte_A ^ feedforward_A); B_out = (shift_byte_B ^ and_byte_B ^ feedforward_B); C_out = (shift_byte_C ^ and_byte_C ^ feedforward_C); /* Feed the output of each shift register into the next, * * after XORing it with the feedback byte. */ set_block_at(76, A_out^feedback_B, tks->srB); set_block_at(103, B_out^feedback_C, tks->srC); set_block_at(85, C_out^feedback_A, tks->srA); return (A_out ^ B_out ^ C_out); }
uint64_t write_file(file_descriptor* fd, void* buf, uint64_t length) { // Store number of bytes written. uint64_t written = 0; int read_error, write_error; // Pull inode. inode_t* inode = &table[fd->inode]; // Allocate room for a block size in memory. void* block = (void*)malloc(BLOCK_SZ); // Write from block at RW pointer until length is complete. int starting_block_index = fd->rwptr / BLOCK_SZ; int current_block_count = starting_block_index; while (length) { // Get block index. int block_index = get_block_at(inode, current_block_count, true); if (block_index < 0) { perror("write_file()"); break; } // Read from block. clear_block(block, 0, BLOCK_SZ); read_error = read_blocks(block_index, 1, block); if (read_error < 0) { perror("write_file(): read chunk from block"); break; } // Modify block in memory. for (int j = fd->rwptr % BLOCK_SZ; j < BLOCK_SZ; j++) { // Copy current byte into buffer. memcpy(block + j, buf, 1); // Increment pointers. fd->rwptr += 1; buf += 1; // Increment number written. written += 1; // Decrement length. length -= 1; if (length == 0) { // Done in the middle of a block. break; } } // Write block. write_error = write_blocks(block_index, 1, block); if (write_error < 0) { perror("write_file(): write chunk to block"); break; } // Increment block. current_block_count += 1; } // Free block. free(block); // Update inode size. if (fd->rwptr > inode->size) { inode->size = fd->rwptr; } // Write inodes and free blocks. write_inode_table(); write_free_blocks(); // Return number of bytes written. return written; }
uint64_t read_file(file_descriptor* fd, void* buf, uint64_t length) { // Store number of bytes read. uint64_t read = 0; int read_error; // Pull inode. inode_t* inode = &table[fd->inode]; // Allocate room for a block size in memory. void* block = (void*)malloc(BLOCK_SZ); // Read from block at RW pointer until length is complete. int starting_block_index = fd->rwptr / BLOCK_SZ; int current_block_count = starting_block_index; while (length) { // Get block index. int block_index = get_block_at(inode, current_block_count, false); if (block_index < 0) { perror("read_file()"); break; } // Read from block. clear_block(block, 0, BLOCK_SZ); read_error = read_blocks(block_index, 1, block); if (read_error < 0) { perror("read_file(): read chunk from block"); break; } // Modify block in memory. for (int j = fd->rwptr % BLOCK_SZ; j < BLOCK_SZ; j++) { // Check if EOF. if (fd->rwptr == inode->size) { // Reached end of file. Done. break; } // Copy current byte into buffer. memcpy(buf, block + j, 1); // Increment pointers. fd->rwptr += 1; buf += 1; // Increment number of bytes read. read += 1; // Decrement length. length -= 1; if (length == 0) { // Done in the middle of a block. break; } } // Increment block. current_block_count += 1; } // Free memory buffer. free(block); // Return bytes read. return read; }