Skinny-C
 All Data Structures Files Functions Variables Groups Pages
skinny64-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 "skinny64-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 Skinny64Key_t *ks);
36  void (*decrypt)(void *output, const void *input, const Skinny64Key_t *ks);
37 
38 } Skinny64ParallelECBVtable_t;
39 
40 void _skinny64_parallel_encrypt_vec128
41  (void *output, const void *input, const Skinny64Key_t *ks);
42 void _skinny64_parallel_decrypt_vec128
43  (void *output, const void *input, const Skinny64Key_t *ks);
44 
45 static Skinny64ParallelECBVtable_t const skinny64_parallel_ecb_vec128 = {
46  _skinny64_parallel_encrypt_vec128,
47  _skinny64_parallel_decrypt_vec128
48 };
49 
53 {
54  Skinny64Key_t *ctx;
55  if ((ctx = calloc(1, sizeof(Skinny64Key_t))) == NULL)
56  return 0;
57  ecb->vtable = 0;
58  ecb->ctx = ctx;
60  if (_skinny_has_vec128())
61  ecb->vtable = &skinny64_parallel_ecb_vec128;
62  return 1;
63 }
64 
66 {
67  if (ecb && ecb->ctx) {
68  skinny_cleanse(ecb->ctx, sizeof(Skinny64Key_t));
69  free(ecb->ctx);
70  ecb->ctx = 0;
71  }
72 }
73 
75  (Skinny64ParallelECB_t *ecb, const void *key, unsigned size)
76 {
77  Skinny64Key_t *ks;
78  if (!ecb || !ecb->ctx)
79  return 0;
80  ks = ecb->ctx;
81  return skinny64_set_key(ks, key, size);
82 }
83 
85  (void *output, const void *input, size_t size,
86  const Skinny64ParallelECB_t *ecb)
87 {
88  const Skinny64Key_t *ks;
89  const Skinny64ParallelECBVtable_t *vtable;
90 
91  /* Validate the parameters */
92  if (!ecb || !ecb->ctx || (size % SKINNY64_BLOCK_SIZE) != 0)
93  return 0;
94  ks = ecb->ctx;
95 
96  /* Process major blocks with the vectorized back end */
97  vtable = ecb->vtable;
98  if (vtable) {
99  size_t psize = ecb->parallel_size;
100  while (size >= psize) {
101  (*(vtable->encrypt))(output, input, ks);
102  output += psize;
103  input += psize;
104  size -= psize;
105  }
106  }
107 
108  /* Process any left-over blocks with the non-parallel implementation */
109  while (size >= SKINNY64_BLOCK_SIZE) {
110  skinny64_ecb_encrypt(output, input, ks);
111  output += SKINNY64_BLOCK_SIZE;
112  input += SKINNY64_BLOCK_SIZE;
113  size -= SKINNY64_BLOCK_SIZE;
114  }
115  return 1;
116 }
117 
119  (void *output, const void *input, size_t size,
120  const Skinny64ParallelECB_t *ecb)
121 {
122  const Skinny64Key_t *ks;
123  const Skinny64ParallelECBVtable_t *vtable;
124 
125  /* Validate the parameters */
126  if (!ecb || !ecb->ctx || (size % SKINNY64_BLOCK_SIZE) != 0)
127  return 0;
128  ks = ecb->ctx;
129 
130  /* Process major blocks with the vectorized back end */
131  vtable = ecb->vtable;
132  if (vtable) {
133  size_t psize = ecb->parallel_size;
134  while (size >= psize) {
135  (*(vtable->decrypt))(output, input, ks);
136  output += psize;
137  input += psize;
138  size -= psize;
139  }
140  }
141 
142  /* Process any left-over blocks with the non-parallel implementation */
143  while (size >= SKINNY64_BLOCK_SIZE) {
144  skinny64_ecb_decrypt(output, input, ks);
145  output += SKINNY64_BLOCK_SIZE;
146  input += SKINNY64_BLOCK_SIZE;
147  size -= SKINNY64_BLOCK_SIZE;
148  }
149  return 1;
150 }
int skinny64_parallel_ecb_init(Skinny64ParallelECB_t *ecb)
Initializes Skinny-64 in parallel ECB mode.
int skinny64_set_key(Skinny64Key_t *ks, const void *key, unsigned size)
Sets the key schedule for a Skinny64 block cipher.
void skinny64_ecb_decrypt(void *output, const void *input, const Skinny64Key_t *ks)
Decrypts a single block using the Skinny64 block cipher in ECB mode.
void skinny64_ecb_encrypt(void *output, const void *input, const Skinny64Key_t *ks)
Encrypts a single block using the Skinny64 block cipher in ECB mode.
void skinny64_parallel_ecb_cleanup(Skinny64ParallelECB_t *ecb)
Cleans up a parallel ECB control block for Skinny-64.
Key schedule for Skinny64 block ciphers.
#define SKINNY64_BLOCK_SIZE
Size of a block for Skinny64 block ciphers.
int skinny64_parallel_ecb_set_key(Skinny64ParallelECB_t *ecb, const void *key, unsigned size)
Sets the key schedule for a Skinny64 block cipher in parallel ECB mode.
State information for Skinny-64 in parallel ECB mode.
int skinny64_parallel_ecb_decrypt(void *output, const void *input, size_t size, const Skinny64ParallelECB_t *ecb)
Decrypt a block of data using Skinny-64 in parallel ECB mode.
int skinny64_parallel_ecb_encrypt(void *output, const void *input, size_t size, const Skinny64ParallelECB_t *ecb)
Encrypt a block of data using Skinny-64 in parallel ECB mode.