comment some prints, use correct boundaries when copying ciphertext buffer
[openpower-isa.git] / crypto / chacha20 / src / xchacha20_wrapper.c
1 #include <Python.h>
2 #include <stdint.h>
3 #include <stdio.h>
4
5 #include "pypowersim_wrapper_common.h"
6 #include "xchacha20_wrapper.h"
7 #include "xchacha20.h"
8
9 void xchacha_hchacha20_svp64(uint8_t *out, const uint8_t *in, const uint8_t *k) {
10
11 // These cannot be the same pointer as the original function, as it is really a separate CPU/RAM
12 // we have to memcpy from input to this pointer, the address was chosen arbitrarily
13 uint64_t inptr_svp64 = 0x100000;
14 uint64_t outptr_svp64 = 0x200000;
15 uint64_t keyptr_svp64 = 0x300000;
16
17 // Create the pypowersim_state
18 pypowersim_state_t *state = pypowersim_prepare();
19
20 // Change the relevant elements, mandatory: body
21 state->binary = PyBytes_FromStringAndSize((const char *)&xchacha_hchacha20_svp64_real, 10000);
22 // Set GPR #3 to the output pointer
23 PyObject *out_address = PyLong_FromUnsignedLongLong(outptr_svp64);
24 PyList_SetItem(state->initial_regs, 3, out_address);
25
26 // Set GPR #4 to the input pointer
27 PyObject *in_address = PyLong_FromUnsignedLongLong(inptr_svp64);
28 PyList_SetItem(state->initial_regs, 4, in_address);
29
30 // Load data into buffer from real memory
31 for (int i=0; i < 16; i += 8) {
32 PyObject *svp64_address = PyLong_FromUnsignedLongLong(inptr_svp64 + i);
33 uint64_t *inptr64 = (uint64_t *) in;
34 PyObject *word = PyLong_FromUnsignedLongLong(*inptr64);
35 PyDict_SetItem(state->initial_mem, svp64_address, word);
36 in += 8;
37 }
38
39 // Set GPR #5 to the key pointer
40 PyObject *key_address = PyLong_FromUnsignedLongLong(keyptr_svp64);
41 PyList_SetItem(state->initial_regs, 5, key_address);
42
43 // Load data into buffer from real memory
44 for (int i=0; i < 32; i += 8) {
45 PyObject *svp64_address = PyLong_FromUnsignedLongLong(keyptr_svp64 + i);
46 uint64_t *keyptr64 = (uint64_t *) k;
47 PyObject *word = PyLong_FromUnsignedLongLong(*keyptr64);
48 PyDict_SetItem(state->initial_mem, svp64_address, word);
49 k += 8;
50 }
51
52 // Prepare the arguments object for the call
53 pypowersim_prepareargs(state);
54
55 // Call the function and get the resulting object
56 state->result_obj = PyObject_CallObject(state->simulator, state->args);
57 if (!state->result_obj) {
58 PyErr_Print();
59 printf("Error invoking 'run_a_simulation'\n");
60 pypowersim_finalize(state);
61 exit(1);
62 }
63
64 PyObject *memobj = PyObject_GetAttrString(state->result_obj, "mem");
65 if (!memobj) {
66 PyErr_Print();
67 Py_DECREF(state->result_obj);
68 printf("Error getting mem object\n");
69 }
70
71 PyObject *mem = PyObject_GetAttrString(memobj, "mem");
72 if (!mem) {
73 PyErr_Print();
74 Py_DECREF(state->result_obj);
75 printf("Error getting mem dict\n");
76 }
77 uint64_t *outptr64 = (uint64_t *) out;
78 for (int i=0; i < 32; i += 8) {
79 PyObject *svp64_address = PyLong_FromUnsignedLongLong((outptr_svp64 + i)/8);
80 PyObject *pyval = PyDict_GetItem(mem, svp64_address);
81 uint64_t val = PyLong_AsUnsignedLongLong(pyval);
82 *outptr64 = val;
83 outptr64++;
84 }
85 }
86
87 void xchacha_encrypt_bytes_svp64(XChaCha_ctx *ctx, const uint8_t *m, uint8_t *c, uint32_t bytes) {
88 /*uint8_t c2[1000];
89 XChaCha_ctx ctx2;
90 memcpy(&ctx2, ctx, sizeof(XChaCha_ctx));
91 xchacha_encrypt_bytes(&ctx2, m, c2, bytes);*/
92
93 // These cannot be the same pointer as the original function, as it is really a separate CPU/RAM
94 // we have to memcpy from input to this pointer, the address was chosen arbitrarily
95 uint64_t ctxptr_svp64 = 0x100000;
96 uint64_t mptr_svp64 = 0x200000;
97 uint64_t cptr_svp64 = 0x300000;
98
99 // Create the pypowersim_state
100 pypowersim_state_t *state = pypowersim_prepare();
101
102 // Change the relevant elements
103 state->binary = PyBytes_FromStringAndSize((const char *)&xchacha_encrypt_bytes_svp64_real, 10000);
104
105 // Set GPR #3 to the output pointer
106 PyObject *ctxptr_address = PyLong_FromUnsignedLongLong(ctxptr_svp64);
107 PyList_SetItem(state->initial_regs, 3, ctxptr_address);
108
109 // Load data into buffer from real memory
110 uint8_t *ctx_u8ptr = (uint8_t *) ctx;
111 for (size_t i=0; i < 64; i += 8) {
112 PyObject *svp64_address = PyLong_FromUnsignedLongLong(ctxptr_svp64);
113 uint64_t *ctxptr64 = (uint64_t *) ctx_u8ptr;
114 /*printf("ctx[%ld]\t: %p -> %02x %02x %02x %02x %02x %02x %02x %02x\n", i, ctxptr64, ctx_u8ptr[0], ctx_u8ptr[1], ctx_u8ptr[2], ctx_u8ptr[3],
115 ctx_u8ptr[4], ctx_u8ptr[5], ctx_u8ptr[6], ctx_u8ptr[7]);
116 printf("val\t: %016lx -> %016lx\n", *ctxptr64, ctxptr_svp64);*/
117 PyObject *word = PyLong_FromUnsignedLongLong(*ctxptr64);
118 PyDict_SetItem(state->initial_mem, svp64_address, word);
119 ctx_u8ptr += 8;
120 ctxptr_svp64 += 8;
121 }
122
123 // Set GPR #4 to the input pointer
124 PyObject *mptr_address = PyLong_FromUnsignedLongLong(mptr_svp64);
125 PyList_SetItem(state->initial_regs, 4, mptr_address);
126
127 uint32_t bytes_rem = bytes % 8;
128 bytes -= bytes_rem;
129 // Load data into buffer from real memory
130 for (size_t i=0; i < bytes; i += 8) {
131 PyObject *svp64_address = PyLong_FromUnsignedLongLong(mptr_svp64);
132 uint64_t *mptr64 = (uint64_t *) m;
133 /*printf("m[%ld] \t: %p -> %02x %02x %02x %02x %02x %02x %02x %02x\n", i, mptr64, m[0], m[1], m[2], m[3],
134 m[4], m[5], m[6], m[7]);
135
136 printf("val \t: %016lx -> %016lx\n", *mptr64, mptr_svp64);*/
137 PyObject *word = PyLong_FromUnsignedLongLong(*mptr64);
138 PyDict_SetItem(state->initial_mem, svp64_address, word);
139 m += 8;
140 mptr_svp64 += 8;
141 }
142 // Load remaining bytes
143 PyObject *svp64_address = PyLong_FromUnsignedLongLong(mptr_svp64);
144 uint64_t mptr64 = 0;
145 uint8_t *mptr8 = (uint8_t *) &mptr64;
146 for (size_t i=0; i < bytes_rem; i++) {
147 mptr8[i] = m[i];
148 }
149 PyObject *word = PyLong_FromUnsignedLongLong(mptr64);
150 PyDict_SetItem(state->initial_mem, svp64_address, word);
151
152 // Set GPR #5 to the cipher pointer
153 PyObject *cptr_address = PyLong_FromUnsignedLongLong(cptr_svp64);
154 PyList_SetItem(state->initial_regs, 5, cptr_address);
155
156 // Set GPR #r65 to the cipher pointer
157 PyObject *bytes_svp64 = PyLong_FromUnsignedLongLong(bytes);
158 PyList_SetItem(state->initial_regs, 6, bytes_svp64);
159
160 // Prepare the arguments object for the call
161 pypowersim_prepareargs(state);
162
163 // Call the function and get the resulting object
164 state->result_obj = PyObject_CallObject(state->simulator, state->args);
165 if (!state->result_obj) {
166 PyErr_Print();
167 printf("Error invoking 'run_a_simulation'\n");
168 pypowersim_finalize(state);
169 exit(1);
170 }
171
172 PyObject *memobj = PyObject_GetAttrString(state->result_obj, "mem");
173 if (!memobj) {
174 PyErr_Print();
175 Py_DECREF(state->result_obj);
176 printf("Error getting mem object\n");
177 }
178
179 PyObject *mem = PyObject_GetAttrString(memobj, "mem");
180 if (!mem) {
181 PyErr_Print();
182 Py_DECREF(state->result_obj);
183 printf("Error getting mem dict\n");
184 }
185
186 uint64_t *cptr64 = (uint64_t *) c;
187 for (size_t i=0; i < (bytes/8+1)*8; i += 8) {
188 PyObject *svp64_address = PyLong_FromUnsignedLongLong((cptr_svp64 + i)/8);
189 PyObject *pyval = PyDict_GetItem(mem, svp64_address);
190 uint64_t val = PyLong_AsUnsignedLongLong(pyval);
191 *cptr64 = val;
192 //printf("c: %p -> %016lx\t val: %016lx -> %lx\n", cptr64, *cptr64, val, cptr_svp64 + i);
193 cptr64++;
194 }
195 /*
196 for (size_t i=0; i < (bytes/8+1)*8; i+= 8) {
197 printf("c[%ld] : %02x %02x %02x %02x %02x %02x %02x %02x\n", i, c[i+0], c[i+1], c[i+2], c[i+3],
198 c[i+4], c[i+5], c[i+6], c[i+7]);
199 printf("c2[%ld] : %02x %02x %02x %02x %02x %02x %02x %02x\n", i, c2[i+0], c2[i+1], c2[i+2], c2[i+3],
200 c2[i+4], c2[i+5], c2[i+6], c2[i+7]);
201 }*/
202
203 }