int MP4_moov_uuid_parse(uint8_t *uuid_data, uint32_t data_len, char *title) { uint8_t *data = uuid_data; uint32_t uuid_len = read_be32(data); data += sizeof(uint32_t); if ( uuid_len != data_len ) { return 0; } //printf("uuid len = %08lx\n", uuid_len); // "MTDT" tag expected uint32_t tag = read_be32(data); if ( tag != 0x4d544454 ) { return 0; } data += sizeof(uint32_t); //printf("tag = %08lx\n", tag); if ( read_be16(data) != 0x0001 ) { return 0; } data += sizeof(uint16_t); uint16_t title_len = (read_be16(data) - 10) / 2; data += sizeof(uint16_t); if ( read_be32(data) != 0x00000001 ) { return 0; } data += sizeof(uint32_t); uint16_t lang_code = read_be16(data); data += sizeof(uint16_t); if ( read_be16(data) != 0x0001 ) { return 0; } data += sizeof(uint16_t); //printf("title len = %04lx (%d) \n", title_len, title_len); if ( title_len > (data_len - (data - uuid_data)) ) { title_len = data_len - (data - uuid_data) - 1; } for(uint16_t i = 0; i < title_len; i++) { uint16_t wc = read_be16(data); //printf("\twc=%04x\n", wc); data += sizeof(uint16_t); title[i] = (char)(wc & 0xff); } title[title_len] = 0; return 1; }
void Key_file::Entry::load (std::istream& in) { while (true) { uint32_t field_id; if (!read_be32(in, field_id)) { throw Malformed(); } if (field_id == KEY_FIELD_END) { break; } uint32_t field_len; if (!read_be32(in, field_len)) { throw Malformed(); } if (field_id == KEY_FIELD_VERSION) { if (field_len != 4) { throw Malformed(); } if (!read_be32(in, version)) { throw Malformed(); } } else if (field_id == KEY_FIELD_AES_KEY) { if (field_len != AES_KEY_LEN) { throw Malformed(); } in.read(reinterpret_cast<char*>(aes_key), AES_KEY_LEN); if (in.gcount() != AES_KEY_LEN) { throw Malformed(); } } else if (field_id == KEY_FIELD_HMAC_KEY) { if (field_len != HMAC_KEY_LEN) { throw Malformed(); } in.read(reinterpret_cast<char*>(hmac_key), HMAC_KEY_LEN); if (in.gcount() != HMAC_KEY_LEN) { throw Malformed(); } } else if (field_id & 1) { // unknown critical field throw Incompatible(); } else { // unknown non-critical field - safe to ignore if (field_len > MAX_FIELD_LEN) { throw Malformed(); } in.ignore(field_len); if (in.gcount() != static_cast<std::streamsize>(field_len)) { throw Malformed(); } } } }
void Key_file::load_header (std::istream& in) { while (true) { uint32_t field_id; if (!read_be32(in, field_id)) { throw Malformed(); } if (field_id == HEADER_FIELD_END) { break; } uint32_t field_len; if (!read_be32(in, field_len)) { throw Malformed(); } if (field_id == HEADER_FIELD_KEY_NAME) { if (field_len > KEY_NAME_MAX_LEN) { throw Malformed(); } if (field_len == 0) { // special case field_len==0 to avoid possible undefined behavior // edge cases with an empty std::vector (particularly, &bytes[0]). key_name.clear(); } else { std::vector<char> bytes(field_len); in.read(&bytes[0], field_len); if (in.gcount() != static_cast<std::streamsize>(field_len)) { throw Malformed(); } key_name.assign(&bytes[0], field_len); } if (!validate_key_name(key_name.c_str())) { key_name.clear(); throw Malformed(); } } else if (field_id & 1) { // unknown critical field throw Incompatible(); } else { // unknown non-critical field - safe to ignore if (field_len > MAX_FIELD_LEN) { throw Malformed(); } in.ignore(field_len); if (in.gcount() != static_cast<std::streamsize>(field_len)) { throw Malformed(); } } } }
fluidStream(std::istream *_fstream) : alureStream(_fstream), Divisions(100), format(AL_NONE), sampleRate(48000), samplesPerTick(1.), fluidSettings(NULL), fluidSynth(NULL), fontID(FLUID_FAILED), doFontLoad(true) { if(!fsynth_handle) return; ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); if(device) alcGetIntegerv(device, ALC_FREQUENCY, 1, &sampleRate); char hdr[4]; if(!fstream->read(hdr, 4)) return; if(memcmp(hdr, "MThd", 4) == 0) { ALuint len = read_be32(fstream); if(len != 6) return; int type = read_be16(fstream); if(type != 0 && type != 1) return; ALuint numtracks = read_be16(fstream); Divisions = read_be16(fstream); UpdateTempo(500000); Tracks.resize(numtracks); for(std::vector<MidiTrack>::iterator i = Tracks.begin(), end = Tracks.end();i != end;i++) { if(!fstream->read(hdr, 4) || memcmp(hdr, "MTrk", 4) != 0) return; ALint len = read_be32(fstream); i->data.resize(len); if(!fstream->read(reinterpret_cast<char*>(&i->data[0]), len) || fstream->gcount() != len) return; unsigned long val = i->ReadVarLen(); i->SamplesLeft += val * samplesPerTick; } SetupSynth(); } }
aiffStream(std::istream *_fstream) : alureStream(_fstream), format(0), dataStart(0) { ALubyte buffer[25]; int length; if(!fstream->read(reinterpret_cast<char*>(buffer), 12) || memcmp(buffer, "FORM", 4) != 0 || memcmp(buffer+8, "AIFF", 4) != 0) return; while(!dataStart || format == AL_NONE) { char tag[4]; if(!fstream->read(tag, 4)) break; /* read chunk length */ length = read_be32(fstream); if(memcmp(tag, "COMM", 4) == 0 && length >= 18) { /* mono or stereo data */ channels = read_be16(fstream); /* number of sample frames */ fstream->ignore(4); /* bits per sample */ sampleSize = read_be16(fstream) / 8; /* sample frequency */ samplerate = read_be80extended(fstream); /* block alignment */ blockAlign = channels * sampleSize; format = GetSampleFormat(channels, sampleSize*8, false); length -= 18; } else if(memcmp(tag, "SSND", 4) == 0) { dataStart = fstream->tellg(); dataStart += 8; dataLen = remLen = length - 8; } fstream->seekg(length, std::ios_base::cur); } if(dataStart > 0 && format != AL_NONE) fstream->seekg(dataStart); }
static vod_status_t mp4_decrypt_start_frame(void* ctx, input_frame_t* frame) { mp4_decrypt_state_t* state = ctx; vod_status_t rc; rc = state->frames_source->start_frame(state->frames_source_context, frame); if (rc != VOD_OK) { return rc; } // get the iv if (state->auxiliary_info_pos + MP4_AES_CTR_IV_SIZE > state->auxiliary_info_end) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "mp4_decrypt_start_frame: failed to get iv from auxiliary info"); return VOD_BAD_DATA; } mp4_aes_ctr_set_iv(&state->cipher, state->auxiliary_info_pos); state->auxiliary_info_pos += MP4_AES_CTR_IV_SIZE; if (!state->use_subsamples) { state->encrypted_bytes = UINT_MAX; return VOD_OK; } // get the subsample info if (state->auxiliary_info_pos + sizeof(uint16_t) + sizeof(cenc_sample_auxiliary_data_subsample_t) > state->auxiliary_info_end) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "mp4_decrypt_start_frame: failed to get subsample info from auxiliary info"); return VOD_BAD_DATA; } read_be16(state->auxiliary_info_pos, state->subsample_count); if (state->subsample_count <= 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "mp4_decrypt_start_frame: invalid subsample count"); return VOD_BAD_DATA; } read_be16(state->auxiliary_info_pos, state->clear_bytes); read_be32(state->auxiliary_info_pos, state->encrypted_bytes); state->subsample_count--; return VOD_OK; }
static void vh_calc_checksum(struct volume_header *vh) { uint32_t newsum = 0; unsigned char *buffer = (unsigned char *)vh; unsigned int i; vh->vh_csum = 0; for(i = 0; i < sizeof(struct volume_header); i += 4) newsum -= read_be32(&buffer[i]); write_be32(newsum, (unsigned char *)&vh->vh_csum); }
static unsigned CheckID3v2(util::Stream *st, uint64_t *pos, bool *ok) { *pos = 0; char header[10]; unsigned rc = st->ReadAll(&header, 10); if (rc) { perror("read"); return rc; } if (!memcmp(header, "ID3", 3)) { unsigned char version = header[3]; if (version < 2 || version > 4) { printf(" Bad ID3v2\n"); *ok = false; } else { unsigned len = (header[6] << 21) | (header[7] << 14) | (header[8] << 7) | (header[9]); uint64_t sz = st->GetLength(); if (len > sz-10) { printf(" Bad ID3v2\n"); *ok = false; } if (s_all) { printf(" %u bytes of ID3v2.%u\n", len, version); } unsigned flags = header[4]; uint64_t frame = 0; while (frame < len) { unsigned char frameheader[10]; st->Seek(10 + frame); rc = st->ReadAll(&frameheader, version == 2 ? 6 : 10); if (frameheader[0] == 0) { if (s_all) printf(" %u bytes of padding\n", len-frame); break; } unsigned framelen = 0; if (version == 4) { framelen = read_unsync32(frameheader+4); } else if (version == 3) { framelen = read_be32(frameheader+4); } else if (version == 2) { framelen = read_be24(frameheader+3); } if (framelen) { std::string tag(frameheader, frameheader + ((version==2) ? 3 : 4)); printf(" %u-byte frame (%s)\n", framelen, tag.c_str()); } else { *ok = false; printf(" Bad frame length %u\n", framelen); } frame += framelen + ((version==2) ? 6 : 10); } *pos = len+10; } } return 0; }
static unsigned WalkFrames(util::Stream *st, uint64_t pos, bool *ok) { uint64_t end = st->GetLength(); unsigned int nframes = 0; unsigned int nsilent = 0; bool started = false; unsigned int bitrate = 0; bool vbr = false; uint64_t streamlen = end-pos; while (pos < (end-4)) { unsigned char header[4]; st->Seek(pos); unsigned rc = st->ReadAll(header, 4); if (rc) return rc; FrameHeader fh; fh.x = read_be32(header); if (fh.s.sync != 0x7FF) { printf(" Sync lost at %llu (%08x %08x)\n", (long long unsigned)pos, fh.x, fh.s.sync); *ok = false; return 0; } unsigned int len = FrameLength(fh); if (!len) { printf(" Bogus header %08x at %llu\n", fh.x, (long long unsigned)pos); *ok = false; return 0; } if (s_frames) { printf(" 0x%08llx: frame %u\n", (unsigned long long)pos, nframes); } unsigned char frame[8192]; rc = st->ReadAll(frame, len-4); if (rc) return rc; unsigned int zeroes; if (fh.s.version == 3) { if (fh.s.channelmode == 3) zeroes = 17; else zeroes = 32; } else { if (fh.s.channelmode == 3) zeroes = 9; else zeroes = 17; } bool silent = true; for (unsigned int i=0; i<zeroes && silent; ++i) { if (frame[i]) silent = false; } if (silent && !started) { ++nsilent; if (!memcmp(frame + zeroes, "Xing", 4) || !memcmp(frame + zeroes, "Info", 4)) { if (s_all) { printf(" Info header in frame %u\n", nframes); printf(" Frame count %u\n", read_be32(frame+zeroes+8)); printf(" Stream length %u\n", read_be32(frame+zeroes+12)); } } else if (!memcmp(frame+32, "VBRI", 4)) { if (s_all) printf(" VBRI header in frame %u\n", nframes); } else { started = true; if (s_all) printf(" Audio begins in frame %u\n", nframes); } } else { if (!started) { started = true; if (s_all) printf(" Audio begins in frame %u\n", nframes); } nsilent = 0; } if (started) { unsigned frame_bitrate = BitRate(fh); if (!bitrate) bitrate = frame_bitrate; else if (bitrate != frame_bitrate) vbr = true; } ++nframes; pos += len; } if (s_all) { if (nsilent) printf(" Final %u frames silent\n", nsilent); printf(" %u frames\n", nframes); if (vbr) printf(" Variable bitrate\n"); else printf(" Bitrate=%u CBR\n", bitrate); printf(" MP3 stream length %llu\n", (unsigned long long)streamlen); } return 0; }
static vod_status_t mp4_decrypt_process( mp4_decrypt_state_t* state, size_t size) { u_char* dest = state->output_pos; u_char* src = state->input_pos; vod_status_t rc; size_t cur_size; while (size > 0) { if (state->clear_bytes <= 0 && state->encrypted_bytes <= 0) { // finished a subsample, read the next one if (state->subsample_count <= 0) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "mp4_decrypt_process: exhausted subsample bytes"); return VOD_BAD_DATA; } if (state->auxiliary_info_pos + sizeof(cenc_sample_auxiliary_data_subsample_t) > state->auxiliary_info_end) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "mp4_decrypt_process: failed to get subsample info from auxiliary info"); return VOD_BAD_DATA; } read_be16(state->auxiliary_info_pos, state->clear_bytes); read_be32(state->auxiliary_info_pos, state->encrypted_bytes); state->subsample_count--; } if (state->clear_bytes > 0) { // copy clear bytes cur_size = vod_min(state->clear_bytes, size); dest = vod_copy(dest, src, cur_size); src += cur_size; size -= cur_size; state->clear_bytes -= cur_size; } // decrypt encrypted bytes cur_size = vod_min(state->encrypted_bytes, size); rc = mp4_aes_ctr_process(&state->cipher, dest, src, cur_size); if (rc != VOD_OK) { return rc; } dest += cur_size; src += cur_size; size -= cur_size; state->encrypted_bytes -= cur_size; } state->output_pos = dest; state->input_pos = src; return VOD_OK; }
size_t tpm2_process_command(const void *tpm2_command, size_t command_size, void *tpm2_response, size_t max_response) { uint32_t status; uint32_t expected_status_bits; size_t payload_size; size_t bytes_to_go; const uint8_t *cmd_body = tpm2_command; uint8_t *rsp_body = tpm2_response; union fifo_transfer_buffer fifo_buffer; const int HEADER_SIZE = 6; struct tpm2_info *tpm_info = car_get_var_ptr(&g_tpm_info); /* Do not try using an uninitialized TPM. */ if (!tpm_info->vendor_id) return 0; /* Skip the two byte tag, read the size field. */ payload_size = read_be32(cmd_body + 2); /* Sanity check. */ if (payload_size != command_size) { printk(BIOS_ERR, "Command size mismatch: encoded %zd != requested %zd\n", payload_size, command_size); trace_dump("W", TPM_DATA_FIFO_REG, command_size, cmd_body, 1); printk(BIOS_DEBUG, "\n"); return 0; } /* Let the TPM know that the command is coming. */ write_tpm_sts(TPM_STS_COMMAND_READY); /* * TPM commands and responses written to and read from the FIFO * register (0x24) are datagrams of variable size, prepended by a 6 * byte header. * * The specification description of the state machine is a bit vague, * but from experience it looks like there is no need to wait for the * sts.expect bit to be set, at least with the 9670 and cr50 devices. * Just write the command into FIFO, making sure not to exceed the * burst count or the maximum PDU size, whatever is smaller. */ fifo_buffer.tx_buffer = cmd_body; fifo_transfer(command_size, fifo_buffer, fifo_transmit); /* Now tell the TPM it can start processing the command. */ write_tpm_sts(TPM_STS_GO); /* Now wait for it to report that the response is ready. */ expected_status_bits = TPM_STS_VALID | TPM_STS_DATA_AVAIL; if (!wait_for_status(expected_status_bits, expected_status_bits)) { /* * If timed out, which should never happen, let's at least * print out the offending command. */ trace_dump("W", TPM_DATA_FIFO_REG, command_size, cmd_body, 1); printk(BIOS_DEBUG, "\n"); return 0; } /* * The response is ready, let's read it. First we read the FIFO * payload header, to see how much data to expect. The response header * size is fixed to six bytes, the total payload size is stored in * network order in the last four bytes. */ tpm2_read_reg(TPM_DATA_FIFO_REG, rsp_body, HEADER_SIZE); /* Find out the total payload size, skipping the two byte tag. */ payload_size = read_be32(rsp_body + 2); if (payload_size > max_response) { /* * TODO(vbendeb): at least drain the FIFO here or somehow let * the TPM know that the response can be dropped. */ printk(BIOS_ERR, " TPM response too long (%zd bytes)", payload_size); return 0; } /* * Now let's read all but the last byte in the FIFO to make sure the * status register is showing correct flow control bits: 'more data' * until the last byte and then 'no more data' once the last byte is * read. */ bytes_to_go = payload_size - 1 - HEADER_SIZE; fifo_buffer.rx_buffer = rsp_body + HEADER_SIZE; fifo_transfer(bytes_to_go, fifo_buffer, fifo_receive); /* Verify that there is still data to read. */ read_tpm_sts(&status); if ((status & expected_status_bits) != expected_status_bits) { printk(BIOS_ERR, "unexpected intermediate status %#x\n", status); return 0; } /* Read the last byte of the PDU. */ tpm2_read_reg(TPM_DATA_FIFO_REG, rsp_body + payload_size - 1, 1); /* Terminate the dump, if enabled. */ if (debug_level_) printk(BIOS_DEBUG, "\n"); /* Verify that 'data available' is not asseretd any more. */ read_tpm_sts(&status); if ((status & expected_status_bits) != TPM_STS_VALID) { printk(BIOS_ERR, "unexpected final status %#x\n", status); return 0; } /* Move the TPM back to idle state. */ write_tpm_sts(TPM_STS_COMMAND_READY); return payload_size; }
static int cr50_i2c_tis_recv(struct tpm_chip *chip, uint8_t *buf, size_t buf_len) { size_t burstcnt, current, len, expected; uint8_t addr = TPM_DATA_FIFO(chip->vendor.locality); uint8_t mask = TPM_STS_VALID | TPM_STS_DATA_AVAIL; int status; if (buf_len < TPM_HEADER_SIZE) goto out_err; if (cr50_i2c_wait_burststs(chip, mask, &burstcnt, &status) < 0) { printk(BIOS_ERR, "%s: First chunk not available\n", __func__); goto out_err; } /* Read first chunk of burstcnt bytes */ if (cr50_i2c_read(chip, addr, buf, burstcnt) != 0) { printk(BIOS_ERR, "%s: Read failed\n", __func__); goto out_err; } /* Determine expected data in the return buffer */ expected = read_be32(buf + TPM_RSP_SIZE_BYTE); if (expected > buf_len) { printk(BIOS_ERR, "%s: Too much data: %zu > %zu\n", __func__, expected, buf_len); goto out_err; } /* Now read the rest of the data */ current = burstcnt; while (current < expected) { /* Read updated burst count and check status */ if (cr50_i2c_wait_burststs(chip, mask, &burstcnt, &status) < 0) goto out_err; len = min(burstcnt, expected - current); if (cr50_i2c_read(chip, addr, buf + current, len) != 0) { printk(BIOS_ERR, "%s: Read failed\n", __func__); goto out_err; } current += len; } /* Ensure TPM is done reading data */ if (cr50_i2c_wait_burststs(chip, TPM_STS_VALID, &burstcnt, &status) < 0) goto out_err; if (status & TPM_STS_DATA_AVAIL) { printk(BIOS_ERR, "%s: Data still available\n", __func__); goto out_err; } return current; out_err: /* Abort current transaction if still pending */ if (cr50_i2c_tis_status(chip) & TPM_STS_COMMAND_READY) cr50_i2c_tis_ready(chip); return -1; }
blargg_err_t Nsfe_Emu::load( const header_t& nsfe_tag, Emu_Reader& in ) { // check header if ( memcmp( nsfe_tag.tag, "NSFE", 4 ) ) return "Not an NSFE file"; // free previous info track_name_data.clear(); track_names.clear(); playlist.clear(); track_times.clear(); // default nsf header static const Nsf_Emu::header_t base_header = { 'N','E','S','M','\x1A', // tag 1, // version 1, 1, // track count, first track 0,0,0,0,0,0, // addresses "","","", // strings { 0x1A, 0x41 }, // NTSC rate { 0 }, // banks { 0x20, 0x4E }, // PAL rate 0,0, // flags 0,0,0,0 // unused }; Nsf_Emu::header_t& header = info_; header = base_header; // parse tags int phase = 0; while ( phase != 3 ) { // read size and tag long size = 0; long tag = 0; BLARGG_RETURN_ERR( read_le32( in, &size ) ); BLARGG_RETURN_ERR( read_be32( in, &tag ) ); switch ( tag ) { case 'INFO': { check( phase == 0 ); if ( size < 8 ) return "Bad NSFE file"; nsfe_info_t info; info.track_count = 1; info.first_track = 0; int s = size; if ( s > sizeof info ) s = sizeof info; BLARGG_RETURN_ERR( in.read( &info, s ) ); BLARGG_RETURN_ERR( in.skip( size - s ) ); phase = 1; info_.speed_flags = info.speed_flags; info_.chip_flags = info.chip_flags; info_.track_count = info.track_count; info_.first_track = info.first_track; std::memcpy( info_.load_addr, info.load_addr, 2 * 3 ); break; } case 'BANK': if ( size > sizeof info_.banks ) return "Bad NSFE file"; BLARGG_RETURN_ERR( in.read( info_.banks, size ) ); break; case 'auth': { std::vector<char> chars; std::vector<const char*> strs; BLARGG_RETURN_ERR( read_strs( in, size, chars, strs ) ); int n = strs.size(); if ( n > 3 ) copy_str( strs [3], info_.ripper, sizeof info_.ripper ); if ( n > 2 ) copy_str( strs [2], info_.copyright, sizeof info_.copyright ); if ( n > 1 ) copy_str( strs [1], info_.author, sizeof info_.author ); if ( n > 0 ) copy_str( strs [0], info_.game, sizeof info_.game ); break; } case 'time': { track_times.resize( size / 4 ); for ( int i = 0; i < track_times.size(); i++ ) BLARGG_RETURN_ERR( read_le32( in, &track_times [i] ) ); break; } case 'tlbl': BLARGG_RETURN_ERR( read_strs( in, size, track_name_data, track_names ) ); break; case 'plst': playlist.resize( size ); BLARGG_RETURN_ERR( in.read( &(*playlist.begin()), size ) ); break; case 'DATA': { check( phase == 1 ); phase = 2; Subset_Reader sub( &in, size ); // limit emu to nsf data BLARGG_RETURN_ERR( Nsf_Emu::load( info_, sub ) ); check( sub.remain() == 0 ); break; } case 'NEND': check( phase == 2 ); phase = 3; break; default: // tags that can be skipped start with a lowercase character check( islower( (tag >> 24) & 0xff ) ); BLARGG_RETURN_ERR( in.skip( size ) ); break; } } return blargg_success; }