void comp_lits(rhdtyp *rhead) { size_t offset; uint4 cnt; uint4 align_pad; mliteral *p; /* Literal text pool is formed in stringpool except for the file name/path of the * source module and routine name which will be emitted by emit_literals immediately * following the literal text pool and is considered part of that text pool.*/ offset = (stringpool.free - stringpool.base); offset += PADLEN(offset, NATIVE_WSIZE); rhead->src_full_name.len = source_name_len; rhead->src_full_name.addr = (char *)offset; offset += source_name_len; offset += PADLEN(offset, NATIVE_WSIZE); rhead->routine_name.len = routine_name.len; rhead->routine_name.addr = (char *)offset; offset += routine_name.len; offset += PADLEN(offset, NATIVE_WSIZE); lits_text_size = UINTCAST(offset); offset = 0; dqloop(&literal_chain, que, p) if (p->rt_addr < 0) { p->rt_addr = offset; offset += SIZEOF(mval); } lits_mval_size = UINTCAST(offset); }
gboolean pcapng_write_enhanced_packet(GOutputStream *out, guint if_id, guint64 timestamp, guint captured_len, guint packet_len, const guint8 *packet_data, const ByteChain *options, GError **err) { static const guint8 pad[] = {0,0,0}; ByteChain chain[3]; guint8 header[20]; *(guint32*)(header) = if_id; *(guint32*)(header + 4) = timestamp >> 32; *(guint32*)(header + 8) = timestamp; *(guint32*)(header + 12) = captured_len; *(guint32*)(header + 16) = packet_len; chain[0].len = sizeof(header); chain[0].data.bytes = header; chain[0].next = &chain[1]; chain[1].len = captured_len; chain[1].data.bytes = packet_data; chain[1].next = &chain[2]; chain[2].len = PADLEN(packet_len,4); chain[2].data.bytes = chain[2].len > 0 ? pad : NULL; chain[2].next = (ByteChain*)default_options(options); return pcapng_write_block(out, 0x00000006, chain, err); }
static ByteChain * allocate_option(guint code, gsize length, const guint8 *value) { ByteChain *chain = g_new(ByteChain, 1); guint8 padding = PADLEN(length,4); guint8 *bytes = g_new(guint8, length + 4 + padding); *(guint16*)bytes = code; *(guint16*)(bytes+2) = length; if (length > 0) { memcpy(bytes+4, value, length); } chain->len = length + 4 + padding; chain->data.bytes = bytes; chain->next = NULL; return chain; }
void s2pool_align(mstr *string) { int length, align_padlen; if ((length = string->len) == 0) return; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); if (mstr_native_align) align_padlen = PADLEN(stringpool.free, NATIVE_WSIZE); else align_padlen = 0; if (length + align_padlen > stringpool.top - stringpool.free) stp_gcol(length + align_padlen); stringpool.free += align_padlen; memcpy(stringpool.free, string->addr, length); string->addr = (char *)stringpool.free; stringpool.free += length; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); }
static gboolean pcapng_write_block(GOutputStream *out, guint type, ByteChain *body, GError **err) { static const guint8 pad[] = {0,0,0}; ByteChain chain[4]; guint32 header[2]; gsize body_len = chain_length(body); header[0] = type; header[1] = body_len + 12; chain[0].len = sizeof(header); chain[0].data.bytes = (guint8*)header; chain[0].next = &chain[1]; chain[1].len = 0; chain[1].data.sub_chain = body; chain[1].next = &chain[2]; chain[2].len = PADLEN(body_len, 4); chain[2].data.bytes = chain[2].len == 0 ? (guint8*)NULL : pad; chain[2].next = &chain[3]; chain[3].len = sizeof(header[1]); chain[3].data.bytes = (guint8*)&header[1]; chain[3].next = NULL; return pcapng_write_chain(out, chain, err); }
void obj_code (uint4 src_lines, void *checksum_ctx) { int status; rhdtyp rhead; mline *mlx, *mly; var_tabent *vptr; int4 lnr_pad_len; intrpt_state_t prev_intrpt_state; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(!run_time); obj_init(); /* Define the routine name global symbol. */ define_symbol(GTM_MODULE_DEF_PSECT, (mstr *)&int_module_name, 0); memset(&rhead, 0, SIZEOF(rhead)); alloc_reg(); jmp_opto(); curr_addr = SIZEOF(rhdtyp); cg_phase = CGP_APPROX_ADDR; cg_phase_last = CGP_NOSTATE; code_gen(); code_size = curr_addr; cg_phase = CGP_ADDR_OPT; shrink_jmps(); comp_lits(&rhead); if ((cmd_qlf.qlf & CQ_MACHINE_CODE)) { cg_phase = CGP_ASSEMBLY; code_gen(); } if (!(cmd_qlf.qlf & CQ_OBJECT)) return; rhead.ptext_ptr = SIZEOF(rhead); set_rtnhdr_checksum(&rhead, (gtm_rtn_src_chksum_ctx *)checksum_ctx); rhead.vartab_ptr = code_size; rhead.vartab_len = mvmax; code_size += mvmax * SIZEOF(var_tabent); rhead.labtab_ptr = code_size; rhead.labtab_len = mlmax; code_size += mlmax * SIZEOF(lab_tabent); rhead.lnrtab_ptr = code_size; rhead.lnrtab_len = src_lines; rhead.compiler_qlf = cmd_qlf.qlf; if (cmd_qlf.qlf & CQ_EMBED_SOURCE) { rhead.routine_source_offset = TREF(routine_source_offset); rhead.routine_source_length = (uint4)(stringpool.free - stringpool.base) - TREF(routine_source_offset); } rhead.temp_mvals = sa_temps[TVAL_REF]; rhead.temp_size = sa_temps_offset[TCAD_REF]; code_size += src_lines * SIZEOF(int4); lnr_pad_len = PADLEN(code_size, SECTION_ALIGN_BOUNDARY); code_size += lnr_pad_len; DEFER_INTERRUPTS(INTRPT_IN_OBJECT_FILE_COMPILE, prev_intrpt_state); create_object_file(&rhead); ENABLE_INTERRUPTS(INTRPT_IN_OBJECT_FILE_COMPILE, prev_intrpt_state); cg_phase = CGP_MACHINE; code_gen(); /* Variable table: */ vptr = (var_tabent *)mcalloc(mvmax * SIZEOF(var_tabent)); if (mvartab) walktree(mvartab, cg_var, (char *)&vptr); else assert(0 == mvmax); emit_immed((char *)vptr, mvmax * SIZEOF(var_tabent)); /* Label table: */ if (mlabtab) walktree((mvar *)mlabtab, cg_lab, (char *)rhead.lnrtab_ptr); else assert(0 == mlmax); /* External entry definitions: */ emit_immed((char *)&(mline_root.externalentry->rtaddr), SIZEOF(mline_root.externalentry->rtaddr)); /* line 0 */ for (mlx = mline_root.child; mlx; mlx = mly) { if (mlx->table) emit_immed((char *)&(mlx->externalentry->rtaddr), SIZEOF(mlx->externalentry->rtaddr)); if (0 == (mly = mlx->child)) /* note assignment */ if (0 == (mly = mlx->sibling)) /* note assignment */ for (mly = mlx; ; ) { if (0 == (mly = mly->parent)) /* note assignment */ break; if (mly->sibling) { mly = mly->sibling; break; } } } if (0 != lnr_pad_len) /* emit padding so literal text pool starts on proper boundary */ emit_immed(PADCHARS, lnr_pad_len); # if !defined(__MVS__) && !defined(__s390__) /* assert not valid for instructions on OS390 */ assert(code_size == psect_use_tab[GTM_CODE]); # endif emit_literals(); DEFER_INTERRUPTS(INTRPT_IN_OBJECT_FILE_COMPILE, prev_intrpt_state); finish_object_file(); ENABLE_INTERRUPTS(INTRPT_IN_OBJECT_FILE_COMPILE, prev_intrpt_state); CLOSE_OBJECT_FILE(object_file_des, status); if (-1 == status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM, errno); /* Ready to make object visible. Rename from tmp name to real routine name */ RENAME_TMP_OBJECT_FILE(object_file_name); }
cf_poly1305_init(&poly, polykey, polykey + 16); mem_clean(polykey, sizeof polykey); /* Discard next 32 bytes of chacha20 key stream. */ cf_chacha20_cipher(&chacha, polykey, polykey, sizeof polykey); mem_clean(polykey, sizeof polykey); /* The input to Poly1305 is: * AAD || pad(AAD) || cipher || pad(cipher) || len_64(aad) || len_64(cipher) */ uint8_t padbuf[16] = { 0 }; #define PADLEN(x) (16 - ((x) & 0xf)) /* AAD || pad(AAD) */ cf_poly1305_update(&poly, header, nheader); cf_poly1305_update(&poly, padbuf, PADLEN(nheader)); /* || cipher */ if (mode == ENCRYPT) { /* If we're encrypting, we compute the ciphertext * before inputting it into the MAC. */ cf_chacha20_cipher(&chacha, input, output, nbytes); cf_poly1305_update(&poly, output, nbytes); } else { /* Otherwise: decryption -- input the ciphertext. * Delay actual decryption until we checked the MAC. */ cf_poly1305_update(&poly, input, nbytes); } /* || pad(cipher) */
void obj_code (uint4 src_lines, uint4 checksum) { rhdtyp rhead; mline *mlx, *mly; var_tabent *vptr; int4 lnr_pad_len; assert(!run_time); obj_init(); /* Define the routine name global symbol. */ define_symbol(GTM_MODULE_DEF_PSECT, (mstr *)&int_module_name, 0); memset(&rhead, 0, SIZEOF(rhead)); alloc_reg(); jmp_opto(); curr_addr = SIZEOF(rhdtyp); cg_phase = CGP_APPROX_ADDR; cg_phase_last = CGP_NOSTATE; code_gen(); code_size = curr_addr; cg_phase = CGP_ADDR_OPT; shrink_jmps(); comp_lits(&rhead); if ((cmd_qlf.qlf & CQ_MACHINE_CODE)) { cg_phase = CGP_ASSEMBLY; code_gen(); } if (!(cmd_qlf.qlf & CQ_OBJECT)) return; rhead.ptext_ptr = SIZEOF(rhead); rhead.checksum = checksum; rhead.vartab_ptr = code_size; rhead.vartab_len = mvmax; code_size += mvmax * SIZEOF(var_tabent); rhead.labtab_ptr = code_size; rhead.labtab_len = mlmax; code_size += mlmax * SIZEOF(lab_tabent); rhead.lnrtab_ptr = code_size; rhead.lnrtab_len = src_lines; rhead.compiler_qlf = cmd_qlf.qlf; rhead.temp_mvals = sa_temps[TVAL_REF]; rhead.temp_size = sa_temps_offset[TCAD_REF]; code_size += src_lines * SIZEOF(int4); lnr_pad_len = PADLEN(code_size, SECTION_ALIGN_BOUNDARY); code_size += lnr_pad_len; create_object_file(&rhead); cg_phase = CGP_MACHINE; code_gen(); /* Variable table: */ vptr = (var_tabent *)mcalloc(mvmax * SIZEOF(var_tabent)); if (mvartab) walktree(mvartab, cg_var, (char *)&vptr); else assert(0 == mvmax); emit_immed((char *)vptr, mvmax * SIZEOF(var_tabent)); /* Label table: */ if (mlabtab) walktree((mvar *)mlabtab, cg_lab, (char *)rhead.lnrtab_ptr); else assert(0 == mlmax); /* External entry definitions: */ emit_immed((char *)&(mline_root.externalentry->rtaddr), SIZEOF(mline_root.externalentry->rtaddr)); /* line 0 */ for (mlx = mline_root.child; mlx; mlx = mly) { if (mlx->table) emit_immed((char *)&(mlx->externalentry->rtaddr), SIZEOF(mlx->externalentry->rtaddr)); if (0 == (mly = mlx->child)) /* note assignment */ if (0 == (mly = mlx->sibling)) /* note assignment */ for (mly = mlx; ; ) { if (0 == (mly = mly->parent)) /* note assignment */ break; if (mly->sibling) { mly = mly->sibling; break; } } } if (0 != lnr_pad_len) /* emit padding so literal text pool starts on proper boundary */ emit_immed(PADCHARS, lnr_pad_len); #if !defined(__MVS__) && !defined(__s390__) /* assert not valid for instructions on OS390 */ assert(code_size == psect_use_tab[GTM_CODE]); #endif emit_literals(); close_object_file(); }
void op_indlvadr(mval *target) { boolean_t rval; char *ptr; icode_str indir_src; mname_entry *targ_key; mstr object, *obj; mval *saved_indx; oprtype v; triple *s; uint4 align_padlen, len; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; MV_FORCE_STR(target); indir_src.str = target->str; indir_src.code = indir_lvadr; saved_indx = NULL; if (NULL == (obj = cache_get(&indir_src))) { comp_init(&target->str); switch (window_token) { case TK_IDENT: rval = lvn(&v, OC_SAVPUTINDX, NULL); s = v.oprval.tref; /* this ugliness serves to return a flag compiled code can use to adjust flow */ if (OC_SAVPUTINDX != s->opcode) { /* this block grabs a way to look up the name later and is similar to some code in op_savputindx */ assert(MVAR_REF == s->operand->oprclass); saved_indx = (mval *)malloc(SIZEOF(mval) + SIZEOF(mname_entry) + SIZEOF(mident_fixed)); saved_indx->mvtype = MV_STR; ptr = (char *)saved_indx + SIZEOF(mval); saved_indx->str.addr = ptr; targ_key = (mname_entry *)ptr; ptr += SIZEOF(mname_entry); targ_key->var_name.addr = ptr; len = s->operand[0].oprval.vref->mvname.len; assert(SIZEOF(mident_fixed) > len); memcpy(ptr, s->operand[0].oprval.vref->mvname.addr, len); targ_key->var_name.len = len; saved_indx->str.len = SIZEOF(mname_entry) + len; COMPUTE_HASH_MNAME(targ_key); targ_key->marked = FALSE; MANAGE_FOR_INDX(frame_pointer, TREF(for_nest_level), saved_indx); } break; case TK_ATSIGN: if (rval = indirection(&v)) { /* if the indirection nests, for_ctrl_indr_subs doesn't matter until we get the "real" lvn */ s = newtriple(OC_INDLVADR); s->operand[0] = v; v = put_tref(s); } break; default: stx_error(ERR_VAREXPECTED); break; } if (comp_fini(rval, &object, OC_IRETMVAD, &v, target->str.len)) { /* before cache and execute, tack a little something on at end of object */ assert(indir_src.str.addr == target->str.addr); len = SIZEOF(uint4) * 2; if (NULL != saved_indx) len += SIZEOF(mval) + SIZEOF(mname_entry) + SIZEOF(mident_fixed); /* overlength, but ends aligned */ align_padlen = mstr_native_align ? PADLEN(stringpool.free, NATIVE_WSIZE) : 0; len += align_padlen; ptr = object.addr + object.len + align_padlen; assert((char *)stringpool.free - align_padlen == ptr); assert(ptr + len <= (char *)stringpool.top); /* ind_code, called by comp_fini, reserves to prevent gc */ if (NULL != saved_indx) { /* it's an unsubscripted name, so save the name infomation with the cached object */ memcpy(ptr, (char *)saved_indx, SIZEOF(mval) + saved_indx->str.len); ptr += (len - (SIZEOF(uint4) * 2)); *(uint4 *)ptr = align_padlen; } ptr += SIZEOF(uint4); *(uint4 *)ptr = len; stringpool.free += len; assert((ptr + SIZEOF(uint4)) == (char *)stringpool.free); object.len += len; cache_put(&indir_src, &object); /* this copies the "extended" object to the cache */ comp_indr(&object); } } else { /* if cached, the object has stuff at the end that might need pulling into the run-time context */ ptr = (char *)(obj->addr + obj->len); len = *(uint4 *)(ptr - SIZEOF(uint4)); if (SIZEOF(mval) < len) /* not nested and not subscripted ? */ { /* grab the name information at the end of the cached indirect object and copy it to be useful to FOR */ align_padlen = *(uint4 *)(ptr - (SIZEOF(uint4) * 2)); assert(NATIVE_WSIZE > align_padlen); assert(SIZEOF(mval) + SIZEOF(mname_entry) + SIZEOF(mident_fixed) + (SIZEOF(uint4) * 2) + NATIVE_WSIZE > len); ptr -= (len + align_padlen); saved_indx = (mval *)ptr; assert(MV_STR == saved_indx->mvtype); len = SIZEOF(mval) + saved_indx->str.len; ptr = malloc(len); memcpy(ptr, (char *)saved_indx, len); saved_indx = (mval *)ptr; ptr += SIZEOF(mval); saved_indx->str.addr = ptr; assert(MAX_MIDENT_LEN >= ((mname_entry *)(saved_indx->str.addr))->var_name.len); assert((SIZEOF(mname_entry) + ((mname_entry *)(saved_indx->str.addr))->var_name.len) == saved_indx->str.len); ptr += SIZEOF(mname_entry); ((mname_entry *)(saved_indx->str.addr))->var_name.addr = ptr; len = SIZEOF(mval) + SIZEOF(mname_entry) + SIZEOF(mident_fixed) + (SIZEOF(uint4) * 2); assert(*(uint4 *)(obj->addr + obj->len - SIZEOF(uint4)) == len); MANAGE_FOR_INDX(frame_pointer, TREF(for_nest_level), saved_indx); } comp_indr(obj); } return; }
static int process(const uint8_t key[32], const uint8_t nonce[12], const uint8_t *header, size_t nheader, const uint8_t *input, size_t nbytes, uint8_t *output, int mode, uint8_t tag[16]) { /* First, generate the Poly1305 key by running ChaCha20 with the * given key and a zero counter. The first half of the * 64-byte output is the key. */ uint8_t fullnonce[16] = { 0 }; memcpy(fullnonce + 4, nonce, 12); uint8_t polykey[32] = { 0 }; cf_chacha20_ctx chacha; cf_chacha20_init_custom(&chacha, key, 32, fullnonce, 4); cf_chacha20_cipher(&chacha, polykey, polykey, sizeof polykey); /* Now initialise Poly1305. */ cf_poly1305 poly; cf_poly1305_init(&poly, polykey, polykey + 16); mem_clean(polykey, sizeof polykey); /* Discard next 32 bytes of chacha20 key stream. */ cf_chacha20_cipher(&chacha, polykey, polykey, sizeof polykey); mem_clean(polykey, sizeof polykey); /* The input to Poly1305 is: * AAD || pad(AAD) || cipher || pad(cipher) || len_64(aad) || len_64(cipher) */ uint8_t padbuf[16] = { 0 }; #define PADLEN(x) (16 - ((x) & 0xf)) /* AAD || pad(AAD) */ cf_poly1305_update(&poly, header, nheader); cf_poly1305_update(&poly, padbuf, PADLEN(nheader)); /* || cipher */ if (mode == ENCRYPT) { /* If we're encrypting, we compute the ciphertext * before inputting it into the MAC. */ cf_chacha20_cipher(&chacha, input, output, nbytes); cf_poly1305_update(&poly, output, nbytes); } else { /* Otherwise: decryption -- input the ciphertext. * Delay actual decryption until we checked the MAC. */ cf_poly1305_update(&poly, input, nbytes); } /* || pad(cipher) */ cf_poly1305_update(&poly, padbuf, PADLEN(nbytes)); /* || len_64(aad) || len_64(cipher) */ write64_le(nheader, padbuf); write64_le(nbytes, padbuf + 8); cf_poly1305_update(&poly, padbuf, sizeof padbuf); /* MAC computation is now complete. */ if (mode == ENCRYPT) { cf_poly1305_finish(&poly, tag); mem_clean(&chacha, sizeof chacha); return SUCCESS; } /* Decrypt mode: calculate tag, and check it. * If it's correct, proceed with decryption. */ uint8_t checktag[16]; cf_poly1305_finish(&poly, checktag); if (mem_eq(checktag, tag, sizeof checktag)) { cf_chacha20_cipher(&chacha, input, output, nbytes); mem_clean(&chacha, sizeof chacha); mem_clean(checktag, sizeof checktag); return SUCCESS; } else { mem_clean(output, nbytes); mem_clean(&chacha, sizeof chacha); mem_clean(checktag, sizeof checktag); return FAILURE; } }