Skinny-C
 All Data Structures Files Functions Variables Groups Pages
skinny128-parallel.c
1 /*
2  * Copyright (C) 2017 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "skinny128-parallel.h"
24 #include "skinny-internal.h"
25 #include <stdlib.h>
26 
33 typedef struct
34 {
35  void (*encrypt)(void *output, const void *input, const Skinny128Key_t *ks);
36  void (*decrypt)(void *output, const void *input, const Skinny128Key_t *ks);
37 
38 } Skinny128ParallelECBVtable_t;
39 
40 void _skinny128_parallel_encrypt_vec128
41  (void *output, const void *input, const Skinny128Key_t *ks);
42 void _skinny128_parallel_decrypt_vec128
43  (void *output, const void *input, const Skinny128Key_t *ks);
44 
45 static Skinny128ParallelECBVtable_t const skinny128_parallel_ecb_vec128 = {
46  _skinny128_parallel_encrypt_vec128,
47  _skinny128_parallel_decrypt_vec128
48 };
49 
50 void _skinny128_parallel_encrypt_vec256
51  (void *output, const void *input, const Skinny128Key_t *ks);
52 void _skinny128_parallel_decrypt_vec256
53  (void *output, const void *input, const Skinny128Key_t *ks);
54 
55 static Skinny128ParallelECBVtable_t const skinny128_parallel_ecb_vec256 = {
56  _skinny128_parallel_encrypt_vec256,
57  _skinny128_parallel_decrypt_vec256
58 };
59 
63 {
64  Skinny128Key_t *ctx;
65  if ((ctx = calloc(1, sizeof(Skinny128Key_t))) == NULL)
66  return 0;
67  ecb->vtable = 0;
68  ecb->ctx = ctx;
70  if (_skinny_has_vec128())
71  ecb->vtable = &skinny128_parallel_ecb_vec128;
72  if (_skinny_has_vec256()) {
73  ecb->vtable = &skinny128_parallel_ecb_vec256;
75  }
76  return 1;
77 }
78 
80 {
81  if (ecb && ecb->ctx) {
82  skinny_cleanse(ecb->ctx, sizeof(Skinny128Key_t));
83  free(ecb->ctx);
84  ecb->ctx = 0;
85  }
86 }
87 
89  (Skinny128ParallelECB_t *ecb, const void *key, unsigned size)
90 {
91  Skinny128Key_t *ks;
92  if (!ecb || !ecb->ctx)
93  return 0;
94  ks = ecb->ctx;
95  return skinny128_set_key(ks, key, size);
96 }
97 
99  (void *output, const void *input, size_t size,
100  const Skinny128ParallelECB_t *ecb)
101 {
102  const Skinny128Key_t *ks;
103  const Skinny128ParallelECBVtable_t *vtable;
104 
105  /* Validate the parameters */
106  if (!ecb || !ecb->ctx || (size % SKINNY128_BLOCK_SIZE) != 0)
107  return 0;
108  ks = ecb->ctx;
109 
110  /* Process major blocks with the vectorized back end */
111  vtable = ecb->vtable;
112  if (vtable) {
113  size_t psize = ecb->parallel_size;
114  while (size >= psize) {
115  (*(vtable->encrypt))(output, input, ks);
116  output += psize;
117  input += psize;
118  size -= psize;
119  }
120  }
121 
122  /* Process any left-over blocks with the non-parallel implementation */
123  while (size >= SKINNY128_BLOCK_SIZE) {
124  skinny128_ecb_encrypt(output, input, ks);
125  output += SKINNY128_BLOCK_SIZE;
126  input += SKINNY128_BLOCK_SIZE;
127  size -= SKINNY128_BLOCK_SIZE;
128  }
129  return 1;
130 }
131 
133  (void *output, const void *input, size_t size,
134  const Skinny128ParallelECB_t *ecb)
135 {
136  const Skinny128Key_t *ks;
137  const Skinny128ParallelECBVtable_t *vtable;
138 
139  /* Validate the parameters */
140  if (!ecb || !ecb->ctx || (size % SKINNY128_BLOCK_SIZE) != 0)
141  return 0;
142  ks = ecb->ctx;
143 
144  /* Process major blocks with the vectorized back end */
145  vtable = ecb->vtable;
146  if (vtable) {
147  size_t psize = ecb->parallel_size;
148  while (size >= psize) {
149  (*(vtable->decrypt))(output, input, ks);
150  output += psize;
151  input += psize;
152  size -= psize;
153  }
154  }
155 
156  /* Process any left-over blocks with the non-parallel implementation */
157  while (size >= SKINNY128_BLOCK_SIZE) {
158  skinny128_ecb_decrypt(output, input, ks);
159  output += SKINNY128_BLOCK_SIZE;
160  input += SKINNY128_BLOCK_SIZE;
161  size -= SKINNY128_BLOCK_SIZE;
162  }
163  return 1;
164 }
void skinny128_ecb_encrypt(void *output, const void *input, const Skinny128Key_t *ks)
Encrypts a single block using the Skinny128 block cipher in ECB mode.
Key schedule for Skinny128 block ciphers.
State information for Skinny-128 in parallel ECB mode.
int skinny128_parallel_ecb_encrypt(void *output, const void *input, size_t size, const Skinny128ParallelECB_t *ecb)
Encrypt a block of data using Skinny-128 in parallel ECB mode.
void skinny128_ecb_decrypt(void *output, const void *input, const Skinny128Key_t *ks)
Decrypts a single block using the Skinny128 block cipher in ECB mode.
int skinny128_parallel_ecb_decrypt(void *output, const void *input, size_t size, const Skinny128ParallelECB_t *ecb)
Decrypt a block of data using Skinny-128 in parallel ECB mode.
int skinny128_set_key(Skinny128Key_t *ks, const void *key, unsigned size)
Sets the key schedule for a Skinny128 block cipher.
#define SKINNY128_BLOCK_SIZE
Size of a block for Skinny128 block ciphers.
void skinny128_parallel_ecb_cleanup(Skinny128ParallelECB_t *ecb)
Cleans up a parallel ECB control block for Skinny-128.
int skinny128_parallel_ecb_init(Skinny128ParallelECB_t *ecb)
Initializes Skinny-128 in parallel ECB mode.
int skinny128_parallel_ecb_set_key(Skinny128ParallelECB_t *ecb, const void *key, unsigned size)
Sets the key schedule for a Skinny128 block cipher in parallel ECB mode.