afs_int32 rxkad_EncryptPacket(const struct rx_connection * conn, const fc_KeySchedule * schedule, const fc_InitializationVector * ivec, const int inlen, struct rx_packet * packet) { afs_uint32 xor[2]; struct rx_securityClass *obj; struct rxkad_cprivate *tp; /* s & c have type at same offset */ char *data; int i, tlen, len; len = inlen; obj = rx_SecurityObjectOf(conn); tp = (struct rxkad_cprivate *)obj->privateData; ADD_RXKAD_STATS(bytesEncrypted[rxkad_TypeIndex(tp->type)],len); /* * afs_int32 cksum; * cksum = htonl(0); * * Future option to add cksum here, but for now we just put 0 */ rx_PutInt32(packet, 1 * sizeof(afs_int32), 0); memcpy((void *)xor, (void *)ivec, sizeof(xor)); for (i = 0; len; i++) { data = rx_data(packet, i, tlen); if (!data || !tlen) break; tlen = MIN(len, tlen); fc_cbc_encrypt(data, data, tlen, *schedule, xor, ENCRYPT); len -= tlen; } return 0; }
afs_int32 rxkad_DecryptPacket(const struct rx_connection *conn, const fc_KeySchedule * schedule, const fc_InitializationVector * ivec, const int inlen, struct rx_packet *packet) { afs_uint32 xor[2]; struct rx_securityClass *obj; struct rxkad_cprivate *tp; /* s & c have type at same offset */ char *data; int i, tlen, len; len = inlen; obj = rx_SecurityObjectOf(conn); tp = (struct rxkad_cprivate *)obj->privateData; ADD_RXKAD_STATS(bytesDecrypted[rxkad_TypeIndex(tp->type)],len); memcpy((void *)xor, (void *)ivec, sizeof(xor)); for (i = 0; len; i++) { data = rx_data(packet, i, tlen); if (!data || !tlen) break; tlen = MIN(len, tlen); fc_cbc_encrypt(data, data, tlen, *schedule, xor, DECRYPT); len -= tlen; } /* Do this if packet checksums are ever enabled (below), but * current version just passes zero afs_int32 cksum; cksum = ntohl(rx_GetInt32(packet, 1)); */ return 0; }
static void usb_rx_data_complete(struct usb_request *req, unsigned actual, int status) { if(status != 0) return; if(actual > rx_length) { actual = rx_length; } rx_addr += actual; rx_length -= actual; if(rx_length > 0) { rx_data(); } else { tx_status("OKAY"); rx_cmd(); } }
static void usb_rx_cmd_complete(struct usb_request *req, unsigned actual, int status) { if(status != 0) return; if(actual > 4095) actual = 4095; cmdbuf[actual] = 0; dprintf("\n> %s\n",cmdbuf); // dprintf("usb_rx_cmd_complete() '%s'\n", cmdbuf); if(memcmp(cmdbuf, "reboot", 6) == 0) { tx_status("OKAY"); rx_cmd(); mdelay(100); board_reboot(); } #if 0 if(memcmp(cmdbuf, "debug:", 6) == 0) { void debug(char *cmd, char *resp); memcpy(cmdbuf, "OKAY", 5); tx_status(cmdbuf); rx_cmd(); mdelay(5000); dprintf("NOW!\n"); debug(cmdbuf + 6, cmdbuf + 4); return; } #endif if(memcmp(cmdbuf, "getvar:", 7) == 0) { char response[64]; strcpy(response,"OKAY"); if(!strcmp(cmdbuf + 7, "version")) { strcpy(response + 4, VERSION); } else if(!strcmp(cmdbuf + 7, "product")) { strcpy(response + 4, PRODUCTNAME); } else if(!strcmp(cmdbuf + 7, "serialno")) { strcpy(response + 4, serialno); } else { board_getvar(cmdbuf + 7, response + 4); } tx_status(response); rx_cmd(); return; } if(memcmp(cmdbuf, "download:", 9) == 0) { char status[16]; rx_addr = kernel_addr; rx_length = hex2unsigned(cmdbuf + 9); if (rx_length > (64*1024*1024)) { tx_status("FAILdata too large"); rx_cmd(); return; } kernel_size = rx_length; dprintf("recv data addr=%x size=%x\n", rx_addr, rx_length); strcpy(status,"DATA"); num_to_hex8(rx_length, status + 4); tx_status(status); rx_data(); return; } if(memcmp(cmdbuf, "erase:", 6) == 0){ struct ptentry *ptn; ptn = flash_find_ptn(cmdbuf + 6); if(ptn == 0) { tx_status("FAILpartition does not exist"); rx_cmd(); return; } dprintf("erasing '%s'\n", ptn->name); cprintf("erasing '%s'", ptn->name); if(flash_erase(ptn)) { tx_status("FAILfailed to erase partition"); rx_cmd(); cprintf(" - FAIL\n"); return; } else { dprintf("partition '%s' erased\n", ptn->name); cprintf(" - OKAY\n"); } tx_status("OKAY"); rx_cmd(); return; } if(memcmp(cmdbuf, "flash:", 6) == 0){ struct ptentry *ptn; int extra = 0; ptn = flash_find_ptn(cmdbuf + 6); if(kernel_size == 0) { tx_status("FAILno image downloaded"); rx_cmd(); return; } if(ptn == 0) { tx_status("FAILpartition does not exist"); rx_cmd(); return; } if(!strcmp(ptn->name,"boot") || !strcmp(ptn->name,"recovery")) { if(memcmp((void*) kernel_addr, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { tx_status("FAILimage is not a boot image"); rx_cmd(); return; } } #if REQUIRE_SIGNATURE { unsigned char digest[DIGEST_SIZE]; compute_digest((void*) kernel_addr, kernel_size, digest); if (is_signature_okay(digest, signature, key_engineering)) { dprintf("verified by engineering key\n"); } else { tx_status("FAILsignature did not verify"); rx_cmd(); return; } } #endif if(!strcmp(ptn->name,"system") || !strcmp(ptn->name,"userdata")) { extra = 64; } else { kernel_size = (kernel_size + 2047) & (~2047); } dprintf("writing %d bytes to '%s'\n", kernel_size, ptn->name); cprintf("writing '%s' (%d bytes)", ptn->name, kernel_size); if(flash_write(ptn, extra, (void*) kernel_addr, kernel_size)) { tx_status("FAILflash write failure"); rx_cmd(); cprintf(" - FAIL\n"); return; } else { dprintf("partition '%s' updated\n", ptn->name); cprintf(" - OKAY\n"); } tx_status("OKAY"); rx_cmd(); return; } if(memcmp(cmdbuf, "boot", 4) == 0) { if(init_boot_linux()) { tx_status("FAILinvalid boot image"); rx_cmd(); return; } dprintf("booting linux...\n"); cprintf("\nbooting linux...\n"); tx_status("OKAY"); mdelay(10); usb_shutdown(); boot_linux(); return; } if(memcmp(cmdbuf, "signature", 9) == 0) { if (kernel_size != SIGNATURE_SIZE) { tx_status("FAILsignature not 256 bytes long"); rx_cmd(); return; } memcpy(signature, (void*)kernel_addr, SIGNATURE_SIZE); tx_status("OKAY"); rx_cmd(); return; } tx_status("FAILinvalid command"); rx_cmd(); }