Rizin
unix-like reverse engineering framework and cli tools
crypto_serpent.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017 NicsTr <nicolas.bordes@grenoble-inp.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_lib.h>
5 #include <rz_crypto.h>
6 #include "crypto_serpent_algo.h"
7 
8 static bool serpent_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
9  rz_return_val_if_fail(cry->user && key, false);
10  serpent_state_t *st = (serpent_state_t *)cry->user;
11 
12  if ((keylen != 128 / 8) && (keylen != 192 / 8) && (keylen != 256 / 8)) {
13  return false;
14  }
15  st->key_size = keylen * 8;
16  for (size_t i = 0; i < keylen / 4; i++) {
17  st->key[i] = rz_read_at_le32(key, i * 4);
18  }
19  cry->dir = direction;
20  return true;
21 }
22 
23 static int serpent_get_key_size(RzCrypto *cry) {
24  rz_return_val_if_fail(cry->user, 0);
25  serpent_state_t *st = (serpent_state_t *)cry->user;
26 
27  return st->key_size;
28 }
29 
30 static bool serpent_use(const char *algo) {
31  return !strcmp(algo, "serpent-ecb");
32 }
33 
34 #define BLOCK_SIZE 16
35 
36 static bool update(RzCrypto *cry, const ut8 *buf, int len) {
37  rz_return_val_if_fail(cry->user, 0);
38  serpent_state_t *st = (serpent_state_t *)cry->user;
39  if (len < 1) {
40  return false;
41  }
42 
43  // Pad to the block size, do not append dummy block
44  const int diff = (BLOCK_SIZE - (len % BLOCK_SIZE)) % BLOCK_SIZE;
45  const int size = len + diff;
46  const int blocks = size / BLOCK_SIZE;
47  int i, j;
48 
49  ut8 *const obuf = calloc(4, size / 4);
50  if (!obuf) {
51  return false;
52  }
53  ut32 *const ibuf = calloc(4, size / 4);
54  if (!ibuf) {
55  free(obuf);
56  return false;
57  }
58  ut32 *const tmp = calloc(4, size / 4);
59  if (!tmp) {
60  free(obuf);
61  free(ibuf);
62  return false;
63  }
64 
65  // Construct ut32 blocks from byte stream
66  for (j = 0; j < len / 4; j++) {
67  ibuf[j] = rz_read_le32(buf + 4 * j);
68  }
69  if (len & 0x3) {
70  ut8 tail[4] = { 0 }; // Zero padding
71  memcpy(tail, buf + (len & ~0x3), len & 0x3);
72  ibuf[len / 4] = rz_read_le32(tail);
73  }
74 
75  if (cry->dir == RZ_CRYPTO_DIR_ENCRYPT) {
76  for (i = 0; i < blocks; i++) {
77  // delta in number of ut32
78  const int delta = (BLOCK_SIZE * i) / 4;
79  serpent_encrypt(st, ibuf + delta, tmp + delta);
80  }
81  } else {
82  for (i = 0; i < blocks; i++) {
83  // delta in number of ut32
84  const int delta = (BLOCK_SIZE * i) / 4;
85  serpent_decrypt(st, ibuf + delta, tmp + delta);
86  }
87  }
88 
89  // Construct ut32 blocks from byte stream
90  int k;
91  for (j = 0; j < size / 4; j++) {
92  k = 4 * j;
93  obuf[k] = tmp[j] & 0xff;
94  obuf[k + 1] = (tmp[j] >> 8) & 0xff;
95  obuf[k + 2] = (tmp[j] >> 16) & 0xff;
96  obuf[k + 3] = (tmp[j] >> 24) & 0xff;
97  }
98 
99  rz_crypto_append(cry, obuf, size);
100  free(obuf);
101  free(ibuf);
102  free(tmp);
103  return true;
104 }
105 
106 static bool final(RzCrypto *cry, const ut8 *buf, int len) {
107  return update(cry, buf, len);
108 }
109 
110 static bool serpent_init(RzCrypto *cry) {
111  rz_return_val_if_fail(cry, false);
112 
113  cry->user = RZ_NEW0(serpent_state_t);
114  return cry->user != NULL;
115 }
116 
117 static bool serpent_fini(RzCrypto *cry) {
118  rz_return_val_if_fail(cry, false);
119 
120  free(cry->user);
121  return true;
122 }
123 
125  .name = "serpent-ecb",
126  .author = "NicsTr",
127  .license = "LGPL-3",
128  .set_key = serpent_set_key,
129  .get_key_size = serpent_get_key_size,
130  .use = serpent_use,
131  .update = update,
132  .final = final,
133  .init = serpent_init,
134  .fini = serpent_fini,
135 };
136 
137 #ifndef RZ_PLUGIN_INCORE
140  .data = &rz_crypto_plugin_serpent,
141  .version = RZ_VERSION
142 };
143 #endif
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API int rz_crypto_append(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto.c:175
static bool serpent_init(RzCrypto *cry)
static bool update(RzCrypto *cry, const ut8 *buf, int len)
static bool serpent_use(const char *algo)
RzCryptoPlugin rz_crypto_plugin_serpent
static bool serpent_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction)
Definition: crypto_serpent.c:8
RZ_API RzLibStruct rizin_plugin
static int serpent_get_key_size(RzCrypto *cry)
#define BLOCK_SIZE
static bool serpent_fini(RzCrypto *cry)
void serpent_decrypt(serpent_state_t *st, ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK])
void serpent_encrypt(serpent_state_t *st, ut32 in[DW_BY_BLOCK], ut32 out[DW_BY_BLOCK])
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
uint32_t ut32
const char * k
Definition: dsignal.c:11
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ RZ_CRYPTO_DIR_ENCRYPT
Definition: rz_crypto.h:23
static ut32 rz_read_at_le32(const void *src, size_t offset)
Definition: rz_endian.h:248
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
@ RZ_LIB_TYPE_CRYPTO
Definition: rz_lib.h:81
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_VERSION
Definition: rz_version.h:8
const char * name
Definition: rz_crypto.h:41
void * user
Definition: rz_crypto.h:36
uint64_t blocks
Definition: list.c:104
static st64 delta
Definition: vmenus.c:2425
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
static unsigned char * obuf
Definition: z80asm.c:36