caddr_t ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress) { ctf_buf_t *buf = ctf_buf_new(); ctf_header_t h; caddr_t outbuf; int i; /* * Prepare the header, and create the CTF output buffers. The data * object section and function section are both lists of 2-byte * integers; we pad these out to the next 4-byte boundary if needed. */ h.cth_magic = CTF_MAGIC; h.cth_version = CTF_VERSION; h.cth_flags = do_compress ? CTF_F_COMPRESS : 0; h.cth_parlabel = strtab_insert(&buf->ctb_strtab, iiburst->iib_td->td_parlabel); h.cth_parname = strtab_insert(&buf->ctb_strtab, iiburst->iib_td->td_parname); h.cth_lbloff = 0; (void) list_iter(iiburst->iib_td->td_labels, write_label, buf); pad_buffer(buf, 2); h.cth_objtoff = ctf_buf_cur(buf); for (i = 0; i < iiburst->iib_nobjts; i++) write_objects(iiburst->iib_objts[i], buf); pad_buffer(buf, 2); h.cth_funcoff = ctf_buf_cur(buf); for (i = 0; i < iiburst->iib_nfuncs; i++) write_functions(iiburst->iib_funcs[i], buf); pad_buffer(buf, 4); h.cth_typeoff = ctf_buf_cur(buf); (void) list_iter(iiburst->iib_types, write_type, buf); debug(2, "CTF wrote %d types\n", list_count(iiburst->iib_types)); h.cth_stroff = ctf_buf_cur(buf); h.cth_strlen = strtab_size(&buf->ctb_strtab); /* * We only do compression for ctfmerge, as ctfconvert is only * supposed to be used on intermediary build objects. This is * significantly faster. */ if (do_compress) outbuf = write_compressed_buffer(&h, buf, resszp); else outbuf = write_buffer(&h, buf, resszp); ctf_buf_free(buf); return (outbuf); }
/* Variable (std var header: NUL padded, fixed length) */ int ti82_send_VAR_h(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname) { uint8_t buffer[16]; char trans[17]; buffer[0] = LSB(varsize); buffer[1] = MSB(varsize); buffer[2] = vartype; memcpy(buffer + 3, varname, 8); ticonv_varname_to_utf8_s(handle->model, varname, trans, vartype); ticalcs_info(" PC->TI: VAR (size=0x%04X=%i, id=%02X, name=%s)", varsize, varsize, vartype, trans); if (vartype != TI8283_BKUP) { // backup: special header pad_buffer(buffer + 3, '\0'); TRYF(dbus_send(handle, PC_TI8283, CMD_VAR, 11, buffer)); } else { TRYF(dbus_send(handle, PC_TI8283, CMD_VAR, 9, buffer)); } return 0; }
/* Variable (std var header: NUL padded, fixed length) */ int ti73_send_VAR_h(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname, uint8_t varattr) { uint8_t buffer[16]; buffer[0] = LSB(varsize); buffer[1] = MSB(varsize); buffer[2] = vartype; memcpy(buffer + 3, varname, 8); buffer[11] = 0x00; buffer[12] = (varattr == ATTRB_ARCHIVED) ? 0x80 : 0x00; ticalcs_info(" PC->TI: VAR (size=0x%04X, id=%02X, name=%s, attr=%i)", varsize, vartype, varname, varattr); if (vartype != TI7383_BKUP) { // backup: special header pad_buffer(buffer + 3, '\0'); TRYF(dbus_send(handle, PC_TI7383, CMD_VAR, 11 + EXTRAS, buffer)); } else { TRYF(dbus_send(handle, PC_TI7383, CMD_VAR, 9, buffer)); } return 0; }
/* Request variable (std var header: NUL padded, fixed length) */ int ti73_send_REQ_h(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname, uint8_t varattr) { uint8_t buffer[16] = { 0 }; char trans[17]; buffer[0] = LSB(varsize); buffer[1] = MSB(varsize); buffer[2] = vartype; memcpy(buffer + 3, varname, 8); pad_buffer(buffer + 3, '\0'); buffer[11] = 0x00; buffer[12] = (varattr == ATTRB_ARCHIVED) ? 0x80 : 0x00; ticonv_varname_to_utf8_s(handle->model, varname, trans, vartype); ticalcs_info(" PC->TI: REQ (size=0x%04X, id=%02X, name=%s, attr=%i)", varsize, vartype, trans, varattr); if (vartype != TI83p_IDLIST && vartype != TI83p_GETCERT) { TRYF(dbus_send(handle, PC_TI7383, CMD_REQ, 11 + EXTRAS, buffer)); } else if(vartype != TI83p_GETCERT && handle->model != CALC_TI73) { TRYF(dbus_send(handle, PC_TI7383, CMD_REQ, 11, buffer)); } else { TRYF(dbus_send(handle, PC_TI73, CMD_REQ, 3, buffer)); } return 0; }
/* FLASH (special var header: size, id, flag, offset, page) */ int ti73_send_REQ2_h(CalcHandle* handle, uint16_t appsize, uint8_t apptype, const char *appname, uint8_t appattr) { uint8_t buffer[16] = { 0 }; buffer[0] = LSB(appsize); buffer[1] = MSB(appsize); buffer[2] = apptype; memcpy(buffer + 3, appname, 8); pad_buffer(buffer + 3, '\0'); ticalcs_info(" PC->TI: REQ (size=0x%04X, id=%02X, name=%s)", appsize, apptype, appname); TRYF(dbus_send(handle, PC_TI7383, CMD_REQ, 11, buffer)); return 0; }
/* Request variable (std var header: NUL padded, fixed length) */ int ti82_send_REQ_h(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname) { uint8_t buffer[16] = { 0 }; char trans[9]; buffer[0] = LSB(varsize); buffer[1] = MSB(varsize); buffer[2] = vartype; memcpy(buffer + 3, varname, 8); pad_buffer(buffer + 3, '\0'); ticonv_varname_to_utf8_s(handle->model, varname, trans, vartype); ticalcs_info(" PC->TI: REQ (size=0x%04X=%i, id=%02X, name=%s)", varsize, varsize, vartype, trans); TRYF(dbus_send(handle, PC_TI8283, CMD_REQ, 11, buffer)); return 0; }
int ti73_send_DEL_h(CalcHandle* handle, uint16_t varsize, uint8_t vartype, const char *varname, uint8_t varattr) { uint8_t buffer[16] = { 0 }; char trans[9]; buffer[0] = LSB(varsize); buffer[1] = MSB(varsize); buffer[2] = vartype == TI83p_APPL ? 0x14 : vartype; memcpy(buffer + 3, varname, 8); pad_buffer(buffer + 3, '\0'); buffer[11] = 0x00; ticonv_varname_to_utf8_s(handle->model, varname, trans, vartype); ticalcs_info(" PC->TI: DEL (name=%s)", trans); TRYF(dbus_send(handle, PC_TI7383, CMD_DEL, 11, buffer)); return 0; }
/* this actually makes the message block and sends it */ int build_message (FILE * in_ptr, byte numdest, char **destination, int *chain, byte numsub, char **subject, char *outfile, int outfileflag, REMAILER * remailer_list, int num_remailers, int client) { int hop, i, j, k, numpackets, packet, copy; long int chunk, tmpchunk; byte iv[8]; byte ivarray[NUM_IV][8], innerkey[24], digest[16]; BUFFER *sendbuff, *bodybuff, *headbuff[21], *message, *tempbuff; long offset; char line[1024]; byte *key[5], packetID[16], commonpacketID[16], messageID[16]; byte tmpbyte; byte packet_type; #ifdef USE_RSAREF PUBLIC_KEY pubKey, *keyPtr[5]; unsigned int numPubKeys, keylen; R_ENVELOPE_CTX rsa_context; #else PUBLIC_KEY pubKey; unsigned int keylen; B_ALGORITHM_OBJ rsa_context; B_ALGORITHM_OBJ des_context; B_KEY_OBJ des_key; #endif unsigned long timestamp; message = new_buffer (); /* prepend destinations to body */ add_to_buffer (message, &numdest, 1); for (i = 0; i < numdest; i++) add_to_buffer (message, destination[i], DESTSIZE); /* add message header lines to body */ add_to_buffer (message, &numsub, 1); for (i = 0; i < numsub; i++) add_to_buffer (message, subject[i], SUBSIZE); offset = message->length; /* add the file to body */ if (in_ptr) { while ((i = fread (line, 1, sizeof (line), in_ptr)) > 0) { if (i < 0) return (-1); /* file error */ add_to_buffer (message, line, i); } fclose (in_ptr); } /* message is complete. */ add_to_random (message->message, message->length); /* Choose the final hop now. */ if (chain[chain[0]] == 0) if (rnd_select (chain[0], chain, remailer_list, num_remailers) < 0) return (-1); #ifdef USE_ZLIB /* should we compress this message? */ if (message->length > PACKETSIZE && check_abilities (remailer_list[chain[chain[0]]].abilities, "C", "")) { tempbuff = new_buffer (); if (compress_buf2buf (message, tempbuff, offset)) { free_buffer (message); message = tempbuff; } else free_buffer (tempbuff); } /* in case it already is compressed, but should not be */ if (!check_abilities (remailer_list[chain[chain[0]]].abilities, "C", "")) { tempbuff = new_buffer (); if (uncompress_buf2buf (message, tempbuff, offset)) { free_buffer (message); message = tempbuff; } else free_buffer (tempbuff); } #endif numpackets = message->length / PACKETSIZE; if (message->length % PACKETSIZE != 0) numpackets++; bodybuff = new_buffer (); sendbuff = new_buffer (); for (i = 1; i <= HOPMAX; i++) headbuff[i] = new_buffer (); our_randombytes (messageID, 16); /* Loop to make one packet at a time */ for (packet = 1; packet <= numpackets; packet++) { /* put the packet in bodybuff, and put the rest back in message */ chunk = message->length; if (chunk > PACKETSIZE) chunk = PACKETSIZE; clear_buffer (bodybuff); tmpchunk = chunk; tmpbyte = tmpchunk & 0xFF; add_to_buffer (bodybuff, &tmpbyte, 1); /* prepend length of data low byte */ tmpchunk = tmpchunk / 256; tmpbyte = tmpchunk & 0xFF; add_to_buffer (bodybuff, &tmpbyte, 1); /* prepend length of data 2nd byte */ tmpchunk = tmpchunk / 256; tmpbyte = tmpchunk & 0xFF; add_to_buffer (bodybuff, &tmpbyte, 1); /* prepend length of data 3rd byte */ tmpchunk = tmpchunk / 256; tmpbyte = tmpchunk & 0xFF; add_to_buffer (bodybuff, &tmpbyte, 1); /* prepend length of data high byte */ add_to_buffer (bodybuff, message->message, chunk); tempbuff = new_buffer (); add_to_buffer (tempbuff, (message->message) + chunk, message->length - chunk); free_buffer (message); message = tempbuff; if (NUMCOPIES < 1 || NUMCOPIES > 10) { fprintf (errlog, "Error: Invalid number of copies.\n"); return (-1); } for (copy = 1; copy <= NUMCOPIES; copy++) { clear_buffer (sendbuff); add_to_buffer (sendbuff, bodybuff->message, bodybuff->length); pad_buffer (sendbuff, PACKETSIZE + 4); /* Create fake header cards */ for (i = chain[0] + 1; i <= HOPMAX; i++) { reset_buffer (headbuff[i]); pad_buffer (headbuff[i], HEADERSIZE); } if (rnd_selectchain (chain, remailer_list, num_remailers) < 0) return (-1); for (hop = chain[0]; hop >= 1; hop--) { /* Get public key for remailer */ if (get_pub_key (remailer_list[abs (chain[hop])].key_ID, &pubKey) != 0) { fprintf (errlog, "Can't get public key!\n"); return (-1); } key[0] = malloc (MAX_ENCRYPTED_KEY_LEN); #ifdef USE_RSAREF numPubKeys = 1; keyPtr[0] = &pubKey; if (R_SealInit (&rsa_context, key, &keylen, iv, numPubKeys, keyPtr, EA_DES_EDE3_CBC, &random_obj) != 0) { fprintf (errlog, "R_SealInit error %x!!!\n", i); exit (-1); } #else B_CreateAlgorithmObject (&rsa_context); B_CreateAlgorithmObject (&des_context); B_SetAlgorithmInfo (rsa_context, AI_PKCS_RSAPublic, 0); B_SetAlgorithmInfo (des_context, AI_DES_EDE3_CBC_IV8, iv); our_randombytes (line, 24); B_CreateKeyObject (&des_key); B_SetKeyInfo (des_key, KI_DES24Strong, line); B_EncryptInit (rsa_context, pubKey, CHOOSER, NULL); B_EncryptUpdate (rsa_context, key[0], &keylen, MAX_ENCRYPTED_KEY_LEN, line, 24, random_obj, NULL); B_EncryptFinal (rsa_context, key[0] + keylen, &k, MAX_ENCRYPTED_KEY_LEN - keylen, random_obj, NULL); B_DestroyAlgorithmObject (&rsa_context); B_DestroyKeyObject (&pubKey); keylen += k; B_EncryptInit (des_context, des_key, CHOOSER, NULL); /* XXX Error handling! */ #endif /* make packet ID and innerkey */ /* packet ID is unique except for duplicates in the last hop */ if (hop != chain[0]) our_randombytes (packetID, 16); else { if (copy == 1) our_randombytes (commonpacketID, 16); memcpy (packetID, commonpacketID, 16); } our_randombytes (innerkey, 24); /* make the iv array */ for (i = 0; i < NUM_IV; i++) our_randombytes (ivarray[i], 8); /* Now build the current header */ reset_buffer (headbuff[hop]); add_to_buffer (headbuff[hop], packetID, 16); /* also like another IV */ add_to_buffer (headbuff[hop], innerkey, 24); /* Key used to encrypt headers and body */ if (hop == chain[0]) { /* if this is the last hop */ if (numpackets == 1) /* final hop */ packet_type = P_FINAL; else /* partial message */ packet_type = P_PARTIAL; add_to_buffer (headbuff[hop], &packet_type, 1); if (packet_type & P_PARTIAL) { tmpbyte = packet; /* which packet is this */ add_to_buffer (headbuff[hop], &tmpbyte, 1); tmpbyte = numpackets; /* out of how many */ add_to_buffer (headbuff[hop], &tmpbyte, 1); } add_to_buffer (headbuff[hop], messageID, 16); add_to_buffer (headbuff[hop], ivarray[BODY_IV], 8); } else { /* this is not the last hop */ packet_type = 0; /* packet type = intermediate packet */ add_to_buffer (headbuff[hop], &packet_type, 1); /* insert the array of IVs */ for (i = 0; i < NUM_IV; i++) { add_to_buffer (headbuff[hop], ivarray[i], 8); } add_to_buffer (headbuff[hop], remailer_list[abs (chain[hop + 1])].name, 80); } /* Extension to original mixmaster format: Use timestamp to prevent replay of old messages. */ add_to_buffer (headbuff[hop], TSMAGIC, sizeof(TSMAGIC)); /* Fuzzy timestamp: don't leak more information than necessary */ timestamp = time(NULL) / SECONDSPERDAY - random_number(4); tmpbyte = timestamp & 0xFF; add_to_buffer (headbuff[hop], &tmpbyte, 1); tmpbyte = (timestamp / 256) & 0xFF; add_to_buffer (headbuff[hop], &tmpbyte, 1); /* Make and append an MD5 checksum of the packet */ make_digest (headbuff[hop], digest); add_to_buffer (headbuff[hop], digest, 16); /* Now pad pre-encrypted header to standard size */ pad_buffer (headbuff[hop], INNERHEAD); /* Done building headbuff[hop] so now RSA it */ tempbuff = new_buffer (); assert (headbuff[hop]->length <= INNERHEAD); #ifdef USE_RSAREF R_SealUpdate (&rsa_context, line, &k, headbuff[hop]->message, headbuff[hop]->length); #else B_EncryptUpdate (des_context, line, &k, sizeof (line), headbuff[hop]->message, headbuff[hop]->length, random_obj, NULL); #endif add_to_buffer (tempbuff, line, k); #ifdef USE_RSAREF R_SealFinal (&rsa_context, line, &k); #else B_EncryptFinal (des_context, line, &k, INNERHEAD - k, random_obj, NULL); B_DestroyAlgorithmObject (&des_context); B_DestroyKeyObject (&des_key); #endif add_to_buffer (tempbuff, line, k); clear_buffer (headbuff[hop]); /* Prepend RSA key ID */ add_to_buffer (headbuff[hop], remailer_list[abs (chain[hop])].key_ID, 16); /* prepend keys and IV to header */ tmpbyte = keylen; add_to_buffer (headbuff[hop], &tmpbyte, 1); add_to_buffer (headbuff[hop], key[0], tmpbyte); add_to_buffer (headbuff[hop], iv, 8); /* add encryped header */ add_to_buffer (headbuff[hop], tempbuff->message, tempbuff->length); free_buffer (tempbuff); /* pad out encrypted header to standard size */ pad_buffer (headbuff[hop], HEADERSIZE); /* encrypt body */ crypt_in_buffer (innerkey, ivarray[BODY_IV], sendbuff, 1); /* encrypt all later headers */ /* i is the index for ivarray */ for (i = 0, j = hop + 1; j <= HOPMAX; j++) crypt_in_buffer (innerkey, ivarray[i++], headbuff[j], 1); } /* hop loop for a given packet */ if (VERBOSE) { fprintf (errlog, "Packet chain: "); for (i = 1; i <= chain[0]; i++) fprintf (errlog, "%s;", remailer_list[abs (chain[i])].shortname); fprintf (errlog, "\n"); } if (strlen (outfile) > 0 && (!streq (outfile, "-")) && (numpackets > 1 || NUMCOPIES > 1)) { sprintf (line, "%s.%d", outfile, (packet - 1) * NUMCOPIES + copy); send_new_packet (headbuff, sendbuff, remailer_list[abs (chain[1])].name, line, outfileflag, client); } else { send_new_packet (headbuff, sendbuff, remailer_list[abs (chain[1])].name, outfile, outfileflag, client); } } /* copies of one packet */ } /* end loop processing packets */ free_buffer (bodybuff); free_buffer (sendbuff); free_buffer (message); for (i = 1; i <= HOPMAX; i++) free_buffer (headbuff[i]); return (0); }