├── .gitignore ├── CMakeLists.txt ├── README.md ├── build └── liblwcipher.so ├── cmake_uninstall.cmake ├── include ├── lwcipher.h ├── present.h ├── simon.h ├── speck.h ├── xtea.h └── xxtea.h ├── internal └── lw_cipher_wrapper.h └── src ├── lw_cipher.c ├── lw_cipher_wrapper.c ├── present.c ├── simon.c ├── speck.c ├── xtea.c └── xxtea.c /.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | .idea 10 | cmake-build-debug 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | 3 | set(CMAKE_C_STANDARD 99) 4 | 5 | project(lwcipher) 6 | 7 | set(SRC_DIR ${CMAKE_SOURCE_DIR}/src) 8 | set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include) 9 | set(INTERNAL_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/internal) 10 | 11 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build) 12 | 13 | add_library(lwcipher SHARED ${SRC_DIR}/lw_cipher.c 14 | ${SRC_DIR}/lw_cipher_wrapper.c 15 | ${SRC_DIR}/present.c 16 | ${SRC_DIR}/simon.c 17 | ${SRC_DIR}/speck.c 18 | ${SRC_DIR}/xtea.c 19 | ${SRC_DIR}/xxtea.c 20 | ) 21 | 22 | target_include_directories(lwcipher PUBLIC ${INCLUDE_DIR}) 23 | target_include_directories(lwcipher PRIVATE ${INTERNAL_INCLUDE_DIR}) 24 | 25 | target_link_libraries(lwcipher PRIVATE ${LWCIPHER_LIBRARY}) 26 | 27 | # install the library and header files, run 'make install' 28 | install(TARGETS lwcipher 29 | LIBRARY DESTINATION /usr/local/lib 30 | ) 31 | 32 | file(GLOB HEADERS ${INCLUDE_DIR}/*.h) 33 | install(FILES ${HEADERS} DESTINATION /usr/local/include/lwcipher) 34 | 35 | # uninstall the installed files , run 'make uninstall' 36 | add_custom_target(uninstall 37 | COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 38 | ) 39 | 40 | # test project 41 | #project(lwcipher_test) 42 | #add_executable(lwcipher_test main.cpp) 43 | #find_library(LWCIPHER_LIBRARY 44 | # NAMES lwcipher 45 | # PATHS /usr/local/lib # 设置库的查找路径 46 | #) 47 | #if(NOT LWCIPHER_LIBRARY) 48 | # message(FATAL_ERROR "liblwcipher.so not found") 49 | #endif() 50 | #target_link_libraries(lwcipher_test ${LWCIPHER_LIBRARY}) 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Low Weight cipher library 2 | 给出了针对低功耗嵌入式设备常用的轻量级密码算法高效实现。 3 | | CipherType | key size(bits) | block_size(B) | MODE | 4 | |------------|----------------|---------------|-------------| 5 | | XTEA | 128 | 8 | ECB,CBC,CTR | 6 | | XXTEA | 128 | 8 | | 7 | | SIMON | ... | | | 8 | | SPECK | ... | | | 9 | | PRESENT | 80 or 128 | 8 | | 10 | 11 | **SIMON:** various block sizes and key sizes 12 | 13 | | Block size (bits) | Key size (bits) | Rounds | 14 | |-------------------|-----------------|--------| 15 | | 32 | 64 | 32 | 16 | | 48 | 72 | 36 | 17 | | 96 | 36 | | 18 | | 64 | 96 | 42 | 19 | | 128 | 44 | | 20 | | 96 | 96 | 52 | 21 | | 144 | 54 | | 22 | | 128 | 128 | 68 | 23 | | 192 | 69 | | 24 | | 256 | 72 | | 25 | 26 | **SPECK:** various block sizes and key sizes 27 | 28 | | Block size (bits) | Key size (bits) | Rounds | 29 | |-------------------|-----------------|--------| 30 | | 2×16 = 32 | 4×16 = 64 | 22 | 31 | | 2×24 = 48 | 3×24 = 72 | 22 | 32 | | 4×24 = 96 | | 23 | 33 | | 2×32 = 64 | 3×32 = 96 | 26 | 34 | | 4×32 = 128 | | 27 | 35 | | 2×48 = 96 | 2×48 = 96 | 28 | 36 | | 3×48 = 144 | | 29 | 37 | | 2×64 = 128 | 2×64 = 128 | 32 | 38 | | 3×64 = 192 | | 33 | 39 | | 4×64 = 256 | | 34 | 40 | 41 | ## Usage 42 | 43 | ```shell 44 | # to build the library 45 | mkdir cmake-build-debug 46 | cd cmake-build-debug 47 | cmake .. 48 | make 49 | ``` 50 | 51 | ```shell 52 | # to install the library 53 | sudo make install 54 | ``` 55 | 56 | ```shell 57 | # to uninstall the library 58 | sudo make uninstall 59 | ``` 60 | 61 | The library will be installed in `/usr/local/lib` and the header files will be installed in `/usr/local/include`. 62 | 63 | -------------------------------------------------------------------------------- /build/liblwcipher.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bleezemlf/liblwcipher/05aee6b34e1094f5a791e0ef01750790f6c02184/build/liblwcipher.so -------------------------------------------------------------------------------- /cmake_uninstall.cmake: -------------------------------------------------------------------------------- 1 | # uninstall.cmake 2 | 3 | if (EXISTS "${CMAKE_BINARY_DIR}/install_manifest.txt") 4 | file(READ "${CMAKE_BINARY_DIR}/install_manifest.txt" files) 5 | string(REGEX REPLACE "\n" ";" files "${files}") 6 | foreach (file ${files}) 7 | message("Removing file: ${file}") 8 | file(REMOVE "${file}") 9 | endforeach() 10 | endif() 11 | -------------------------------------------------------------------------------- /include/lwcipher.h: -------------------------------------------------------------------------------- 1 | #ifndef LWCIPHER_LWCIPHER_H 2 | #define LWCIPHER_LWCIPHER_H 3 | 4 | #include 5 | #include "xtea.h" 6 | #include "xxtea.h" 7 | #include "simon.h" 8 | #include "speck.h" 9 | #include "present.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | /** The selected feature is not available. */ 17 | #define LW_ERR_CIPHER_FEATURE_UNAVAILABLE (-0x6080) 18 | /** Bad input parameters. */ 19 | #define LW_ERR_CIPHER_BAD_INPUT_DATA (-0x6100) 20 | /** Failed to allocate memory. */ 21 | #define LW_ERR_CIPHER_ALLOC_FAILED (-0x6180) 22 | /** Input data contains invalid padding and is rejected. */ 23 | #define LW_ERR_CIPHER_INVALID_PADDING (-0x6200) 24 | /** Decryption of block requires a full block. */ 25 | #define LW_ERR_CIPHER_FULL_BLOCK_EXPECTED (-0x6280) 26 | /** Authentication failed (for AEAD modes). */ 27 | #define LW_ERR_CIPHER_AUTH_FAILED (-0x6300) 28 | /** The context is invalid. For example, because it was freed. */ 29 | #define LW_ERR_CIPHER_INVALID_CONTEXT (-0x6380) 30 | 31 | typedef enum lw_cipher_id_t 32 | { 33 | LW_CIPHER_ID_NONE = 0, 34 | LW_CIPHER_ID_NULL, 35 | LW_CIPHER_ID_XTEA, 36 | LW_CIPHER_ID_XXTEA, 37 | LW_CIPHER_ID_SIMON, 38 | LW_CIPHER_ID_SPECK, 39 | LW_CIPHER_ID_PRESENT 40 | } lw_cipher_id_t; 41 | 42 | typedef enum 43 | { 44 | LW_CIPHER_NONE = 0, 45 | LW_CIPHER_NULL, 46 | LW_CIPHER_XTEA_ECB, 47 | LW_CIPHER_XTEA_CBC, 48 | LW_CIPHER_XTEA_CTR, 49 | LW_CIPHER_XXTEA_ECB, 50 | LW_CIPHER_XXTEA_CBC, 51 | LW_CIPHER_XXTEA_CTR, 52 | LW_CIPHER_SIMON_64_32_ECB, 53 | LW_CIPHER_SIMON_64_32_CBC, 54 | LW_CIPHER_SIMON_64_32_CTR, 55 | LW_CIPHER_SIMON_72_48_ECB, 56 | LW_CIPHER_SIMON_72_48_CBC, 57 | LW_CIPHER_SIMON_72_48_CTR, 58 | LW_CIPHER_SIMON_96_48_ECB, 59 | LW_CIPHER_SIMON_96_48_CBC, 60 | LW_CIPHER_SIMON_96_48_CTR, 61 | LW_CIPHER_SIMON_96_64_ECB, 62 | LW_CIPHER_SIMON_96_64_CBC, 63 | LW_CIPHER_SIMON_96_64_CTR, 64 | LW_CIPHER_SIMON_128_64_ECB, 65 | LW_CIPHER_SIMON_128_64_CBC, 66 | LW_CIPHER_SIMON_128_64_CTR, 67 | LW_CIPHER_SIMON_96_96_ECB, 68 | LW_CIPHER_SIMON_96_96_CBC, 69 | LW_CIPHER_SIMON_96_96_CTR, 70 | LW_CIPHER_SIMON_144_96_ECB, 71 | LW_CIPHER_SIMON_144_96_CBC, 72 | LW_CIPHER_SIMON_144_96_CTR, 73 | LW_CIPHER_SIMON_128_128_ECB, 74 | LW_CIPHER_SIMON_128_128_CBC, 75 | LW_CIPHER_SIMON_128_128_CTR, 76 | LW_CIPHER_SIMON_192_128_ECB, 77 | LW_CIPHER_SIMON_192_128_CBC, 78 | LW_CIPHER_SIMON_192_128_CTR, 79 | LW_CIPHER_SIMON_256_128_ECB, 80 | LW_CIPHER_SIMON_256_128_CBC, 81 | LW_CIPHER_SIMON_256_128_CTR, 82 | LW_CIPHER_SPECK_64_32_ECB, 83 | LW_CIPHER_SPECK_64_32_CBC, 84 | LW_CIPHER_SPECK_64_32_CTR, 85 | LW_CIPHER_SPECK_72_48_ECB, 86 | LW_CIPHER_SPECK_72_48_CBC, 87 | LW_CIPHER_SPECK_72_48_CTR, 88 | LW_CIPHER_SPECK_96_48_ECB, 89 | LW_CIPHER_SPECK_96_48_CBC, 90 | LW_CIPHER_SPECK_96_48_CTR, 91 | LW_CIPHER_SPECK_96_64_ECB, 92 | LW_CIPHER_SPECK_96_64_CBC, 93 | LW_CIPHER_SPECK_96_64_CTR, 94 | LW_CIPHER_SPECK_128_64_ECB, 95 | LW_CIPHER_SPECK_128_64_CBC, 96 | LW_CIPHER_SPECK_128_64_CTR, 97 | LW_CIPHER_SPECK_96_96_ECB, 98 | LW_CIPHER_SPECK_96_96_CBC, 99 | LW_CIPHER_SPECK_96_96_CTR, 100 | LW_CIPHER_SPECK_144_96_ECB, 101 | LW_CIPHER_SPECK_144_96_CBC, 102 | LW_CIPHER_SPECK_144_96_CTR, 103 | LW_CIPHER_SPECK_128_128_ECB, 104 | LW_CIPHER_SPECK_128_128_CBC, 105 | LW_CIPHER_SPECK_128_128_CTR, 106 | LW_CIPHER_SPECK_192_128_ECB, 107 | LW_CIPHER_SPECK_192_128_CBC, 108 | LW_CIPHER_SPECK_192_128_CTR, 109 | LW_CIPHER_SPECK_256_128_ECB, 110 | LW_CIPHER_SPECK_256_128_CBC, 111 | LW_CIPHER_SPECK_256_128_CTR, 112 | LW_CIPHER_PRESENT_80_ECB, 113 | LW_CIPHER_PRESENT_80_CBC, 114 | LW_CIPHER_PRESENT_80_CTR, 115 | LW_CIPHER_PRESENT_128_ECB, 116 | LW_CIPHER_PRESENT_128_CBC, 117 | LW_CIPHER_PRESENT_128_CTR, 118 | } lw_cipher_type_t; 119 | 120 | typedef enum 121 | { 122 | LW_MODE_NONE = 0, 123 | LW_MODE_ECB, 124 | LW_MODE_CBC, 125 | LW_MODE_CTR 126 | } lw_cipher_mode_t; 127 | 128 | typedef enum 129 | { 130 | LW_CIPHER_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ 131 | LW_CIPHER_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ 132 | LW_CIPHER_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ 133 | LW_CIPHER_PADDING_ZEROS, /**< Zero padding (not reversible). */ 134 | LW_CIPHER_PADDING_NONE, /**< Never pad (full blocks only). */ 135 | } lw_cipher_padding_t; 136 | 137 | typedef enum 138 | { 139 | LW_OPERATION_NONE = -1, 140 | LW_ENCRYPT, 141 | LW_DECRYPT 142 | } lw_operation_t; 143 | 144 | #define LW_MAX_IV_LENGTH 16 145 | #define LW_MAX_BLOCK_LENGTH 16 146 | #define LW_MAX_KEY_LENGTH 32 147 | typedef struct lw_cipher_info_t 148 | { 149 | const char *name; 150 | uint8_t block_size; 151 | uint8_t iv_size; 152 | uint16_t key_bitlen; 153 | uint8_t mode; // for example: LW_MODE_ECB 154 | uint8_t type; // for example: LW_CIPHER_XTEA_ECB 155 | uint8_t flags; 156 | uint8_t base_idx; 157 | } lw_cipher_info_t; 158 | 159 | typedef struct lw_cipher_context_t 160 | { 161 | lw_cipher_info_t *cipher_info; 162 | int key_bitlen; 163 | lw_operation_t operation; 164 | 165 | // lw_cipher_padding_t padding; 166 | void (*add_padding)(unsigned char *output, size_t olen, size_t data_len); 167 | 168 | int (*get_padding)(unsigned char *input, size_t ilen, size_t *data_len); 169 | 170 | uint8_t unprocessed_data[LW_MAX_BLOCK_LENGTH]; 171 | size_t unprocessed_len; 172 | uint8_t iv[LW_MAX_IV_LENGTH]; 173 | size_t iv_size; 174 | void *cipher_ctx;//specific cipher context 175 | } lw_cipher_context_t; 176 | 177 | const lw_cipher_info_t *lw_cipher_info_from_type(const lw_cipher_type_t cipher_type); 178 | 179 | const lw_cipher_info_t *lw_cipher_info_from_string(const char *cipher_name); 180 | 181 | const lw_cipher_info_t *lw_cipher_info_from_values(const lw_cipher_id_t cipher_id, 182 | int key_bitlen, 183 | const lw_cipher_mode_t cipher_mode 184 | ); 185 | 186 | static inline lw_cipher_type_t lw_cipher_info_get_type( 187 | const lw_cipher_info_t *info) 188 | { 189 | if (info == NULL) { 190 | return LW_CIPHER_NONE; 191 | } else { 192 | return (lw_cipher_type_t) info->type; 193 | } 194 | } 195 | 196 | static inline lw_cipher_mode_t lw_cipher_info_get_mode( 197 | const lw_cipher_info_t *info) 198 | { 199 | if (info == NULL) { 200 | return LW_MODE_NONE; 201 | } else { 202 | return (lw_cipher_mode_t) info->mode; 203 | } 204 | } 205 | 206 | static inline size_t lw_cipher_info_get_key_bitlen( 207 | lw_cipher_info_t *info) 208 | { 209 | if (info == NULL) { 210 | return 0; 211 | } else { 212 | return info->key_bitlen; 213 | } 214 | } 215 | 216 | static inline const char *lw_cipher_info_get_name( 217 | const lw_cipher_info_t *info) 218 | { 219 | if (info == NULL) { 220 | return NULL; 221 | } else { 222 | return info->name; 223 | } 224 | } 225 | 226 | static inline size_t lw_cipher_info_get_iv_size( 227 | const lw_cipher_info_t *info) 228 | { 229 | if (info == NULL) { 230 | return 0; 231 | } 232 | 233 | return ((size_t) info->iv_size); 234 | } 235 | 236 | static inline size_t lw_cipher_info_get_block_size( 237 | const lw_cipher_info_t *info) 238 | { 239 | if (info == NULL) { 240 | return 0; 241 | } 242 | 243 | return (size_t) (info->block_size); 244 | } 245 | 246 | void lw_cipher_init(lw_cipher_context_t *ctx); 247 | 248 | void lw_cipher_free(lw_cipher_context_t *ctx); 249 | 250 | int lw_cipher_setup(lw_cipher_context_t *ctx, const lw_cipher_info_t *cipher_info); 251 | 252 | static inline unsigned int lw_cipher_get_block_size( 253 | const lw_cipher_context_t *ctx) 254 | { 255 | if (ctx->cipher_info == NULL) { 256 | return 0; 257 | } 258 | 259 | return (unsigned int) ctx->cipher_info->block_size; 260 | } 261 | 262 | static inline lw_cipher_mode_t lw_cipher_get_cipher_mode( 263 | const lw_cipher_context_t *ctx) 264 | { 265 | if (ctx->cipher_info == NULL) { 266 | return LW_MODE_NONE; 267 | } 268 | 269 | return (lw_cipher_mode_t) ctx->cipher_info->mode; 270 | } 271 | 272 | static inline int lw_cipher_get_iv_size( 273 | const lw_cipher_context_t *ctx) 274 | { 275 | if (ctx->cipher_info == NULL) { 276 | return 0; 277 | } 278 | 279 | if (ctx->iv_size != 0) { 280 | return (int) ctx->iv_size; 281 | } 282 | 283 | return (int) (((int) ctx->cipher_info->iv_size)); 284 | } 285 | 286 | static inline lw_cipher_type_t lw_cipher_get_type( 287 | const lw_cipher_context_t *ctx) 288 | { 289 | if (ctx->cipher_info == NULL) { 290 | return LW_CIPHER_NONE; 291 | } 292 | 293 | return (lw_cipher_type_t) ctx->cipher_info->type; 294 | } 295 | 296 | static inline const char *lw_cipher_get_name( 297 | const lw_cipher_context_t *ctx) 298 | { 299 | if (ctx->cipher_info == NULL) { 300 | return 0; 301 | } 302 | 303 | return ctx->cipher_info->name; 304 | } 305 | 306 | static inline int lw_cipher_get_key_bitlen( 307 | const lw_cipher_context_t *ctx) 308 | { 309 | if (ctx->cipher_info == NULL) { 310 | return 0; 311 | } 312 | 313 | return (int) ctx->cipher_info->key_bitlen; 314 | } 315 | 316 | static inline lw_operation_t lw_cipher_get_operation( 317 | const lw_cipher_context_t *ctx) 318 | { 319 | if (ctx->cipher_info == NULL) { 320 | return LW_OPERATION_NONE; 321 | } 322 | 323 | return ctx->operation; 324 | } 325 | 326 | 327 | int lw_cipher_setkey(lw_cipher_context_t *ctx, const uint8_t *key, 328 | unsigned int key_bitlen, const lw_operation_t operation); 329 | 330 | int lw_cipher_set_padding_mode(lw_cipher_context_t *ctx, 331 | lw_cipher_padding_t mode); 332 | 333 | int lw_cipher_set_iv(lw_cipher_context_t *ctx, const unsigned char *iv, 334 | size_t iv_len); 335 | 336 | int lw_cipher_reset(lw_cipher_context_t *ctx); 337 | 338 | int lw_cipher_update(lw_cipher_context_t *ctx, const unsigned char *input, 339 | size_t ilen, unsigned char *output, size_t *olen); 340 | 341 | int lw_cipher_finish(lw_cipher_context_t *ctx, 342 | unsigned char *output, size_t *olen); 343 | 344 | int lw_cipher_crypt(lw_cipher_context_t *ctx, 345 | const unsigned char *iv, size_t iv_len, 346 | const unsigned char *input, size_t ilen, 347 | unsigned char *output, size_t *olen); 348 | 349 | #ifdef __cplusplus 350 | } 351 | #endif 352 | 353 | #endif //LWCIPHER_LWCIPHER_H -------------------------------------------------------------------------------- /include/present.h: -------------------------------------------------------------------------------- 1 | #ifndef LWCIPHER_PRESENT_H 2 | #define LWCIPHER_PRESENT_H 3 | #include 4 | /* 5 | * block size: 64 bits 6 | * key size: 80 bits or 128 bits 7 | * round number: 31 for 80 bits key, 32 for 128 bits key 8 | * round key size : 64 bits 9 | * */ 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | 17 | typedef struct lw_present_context{ 18 | uint8_t key[16]; 19 | uint8_t key_bitlen; 20 | uint8_t round_key[32][8]; 21 | }lw_present_context; 22 | 23 | #define PRESENT_ENCRYPT 1 24 | #define PRESENT_DECRYPT 0 25 | 26 | #define LW_ERR_ERROR_CORRUPTION_DETECTED (-0x000E) /**< Corrupted data detected. */ 27 | #define LW_ERR_PRESENT_INVALID_CONFIG (-0x0050) /**< Invalid data input length. */ 28 | #define LW_ERR_PRESENT_BAD_INPUT_DATA (-0x0051) /**< Bad input parameters to function. */ 29 | #define LW_ERR_PRESENT_INVALID_INPUT_LENGTH (-0x0052) /**< Invalid data input length. */ 30 | 31 | void lw_present_init(lw_present_context *ctx); 32 | 33 | void lw_present_free(lw_present_context *ctx); 34 | 35 | int lw_present_setkey(lw_present_context *ctx, const uint8_t *key, uint16_t key_bitlen); 36 | 37 | int lw_present_crypt_ecb(lw_present_context *ctx, const uint8_t mode, const uint8_t *input, uint8_t *output); 38 | 39 | int lw_present_crypt_cbc(lw_present_context *ctx, const uint8_t mode, size_t length, uint8_t iv[8], 40 | const uint8_t *input, uint8_t *output); 41 | 42 | int lw_present_crypt_ctr(lw_present_context *ctx, size_t length, uint8_t *nc_off, uint8_t nonce_counter[8], 43 | uint8_t stream_block[8], const uint8_t *input, uint8_t *output); 44 | 45 | int lw_present_self_test(int verbose); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif //LWCIPHER_PRESENT_H 52 | -------------------------------------------------------------------------------- /include/simon.h: -------------------------------------------------------------------------------- 1 | #ifndef LWCIPHER_SIMON_H 2 | #define LWCIPHER_SIMON_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct lw_simon_context 12 | { 13 | uint8_t key[32]; // max key size, it can be 8, 9, 12, 16, 18, 24, 32 14 | uint16_t key_bitlen; // in bits 15 | uint8_t block_size; // in bytes 16 | uint8_t round_limit; 17 | uint8_t key_schedule[576]; 18 | uint8_t z_seq; 19 | 20 | void (*encryptPtr)(const uint8_t, const uint8_t *, const uint8_t *, uint8_t *); 21 | 22 | void (*decryptPtr)(const uint8_t, const uint8_t *, const uint8_t *, uint8_t *); 23 | } lw_simon_context; 24 | 25 | typedef struct _bword_24 26 | { 27 | uint32_t data: 24; 28 | } bword_24; 29 | 30 | typedef struct _bword_48 31 | { 32 | uint64_t data: 48; 33 | } bword_48; 34 | 35 | #define SIMON_ENCRYPT 1 36 | #define SIMON_DECRYPT 0 37 | 38 | #define LW_ERR_ERROR_CORRUPTION_DETECTED (-0x000E) /**< Corrupted data detected. */ 39 | #define LW_ERR_SIMON_INVALID_CONFIG (-0x0030) /**< Invalid data input length. */ 40 | #define LW_ERR_SIMON_BAD_INPUT_DATA (-0x0031) /**< Bad input parameters to function. */ 41 | #define LW_ERR_SIMON_INVALID_INPUT_LENGTH (-0x0032) /**< Invalid data input length. */ 42 | 43 | void lw_simon_init(lw_simon_context *ctx, uint8_t block_size); 44 | 45 | void lw_simon_free(lw_simon_context *ctx); 46 | 47 | int lw_simon_setkey(lw_simon_context *ctx, const uint8_t *key, uint16_t key_bitlen); 48 | 49 | void Simon_Encrypt_32(uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 50 | uint8_t *ciphertext); 51 | 52 | void Simon_Encrypt_48(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 53 | uint8_t *ciphertext); 54 | 55 | void Simon_Encrypt_64(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 56 | uint8_t *ciphertext); 57 | 58 | void Simon_Encrypt_96(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 59 | uint8_t *ciphertext); 60 | 61 | void Simon_Encrypt_128(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 62 | uint8_t *ciphertext); 63 | 64 | void Simon_Decrypt_32(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 65 | uint8_t *plaintext); 66 | 67 | void Simon_Decrypt_48(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 68 | uint8_t *plaintext); 69 | 70 | void Simon_Decrypt_64(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 71 | uint8_t *plaintext); 72 | 73 | void Simon_Decrypt_96(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 74 | uint8_t *plaintext); 75 | 76 | void Simon_Decrypt_128(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 77 | uint8_t *plaintext); 78 | 79 | int lw_simon_crypt_ecb(lw_simon_context *ctx, int mode, const uint8_t input[8], 80 | uint8_t output[8]); 81 | 82 | int lw_simon_crypt_cbc(lw_simon_context *ctx, int mode, size_t length, 83 | uint8_t iv[8], const uint8_t *input, uint8_t *output); 84 | 85 | int lw_simon_crypt_ctr(lw_simon_context *ctx, size_t length, uint8_t *nc_off, 86 | uint8_t nonce_counter[8], uint8_t stream_block[8], 87 | const uint8_t *input, uint8_t *output); 88 | 89 | int lw_simon_self_test(int verbose); 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | 95 | #endif //LWCIPHER_SIMON_H 96 | -------------------------------------------------------------------------------- /include/speck.h: -------------------------------------------------------------------------------- 1 | #ifndef LWCIPHER_SPECK_H 2 | #define LWCIPHER_SPECK_H 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef struct lw_speck_context 11 | { 12 | uint8_t key[32]; // max key size, it can be 8, 9, 12, 16, 18, 24, 32 13 | uint16_t key_bitlen; // in bits 14 | uint8_t block_size; // in bytes 15 | uint8_t round_limit; 16 | uint8_t key_schedule[576]; 17 | uint8_t alpha; 18 | uint8_t beta; 19 | 20 | void (*encryptPtr)(const uint8_t, const uint8_t *, const uint8_t *, uint8_t *); 21 | 22 | void (*decryptPtr)(const uint8_t, const uint8_t *, const uint8_t *, uint8_t *); 23 | } lw_speck_context; 24 | 25 | typedef struct _bitword24_t{ 26 | uint32_t data: 24; 27 | } bitword24_t; 28 | 29 | typedef struct _bytes3_t{ 30 | uint8_t data[3]; 31 | } bytes3_t; 32 | 33 | typedef struct _bitword48_t{ 34 | uint64_t data: 48; 35 | } bitword48_t; 36 | 37 | typedef struct _bytes6_t{ 38 | uint8_t data[6]; 39 | } bytes6_t; 40 | 41 | #define SPECK_ENCRYPT 1 42 | #define SPECK_DECRYPT 0 43 | #define LW_ERR_ERROR_CORRUPTION_DETECTED (-0x000E) /**< Corrupted data detected. */ 44 | #define LW_ERR_SPECK_INVALID_CONFIG (-0x0040) /**< Invalid data input length. */ 45 | #define LW_ERR_SPECK_BAD_INPUT_DATA (-0x0041) /**< Bad input parameters to function. */ 46 | #define LW_ERR_SPECK_INVALID_INPUT_LENGTH (-0x0042) /**< Invalid data input length. */ 47 | 48 | void lw_speck_init(lw_speck_context *ctx, uint8_t block_size); 49 | 50 | void lw_speck_free(lw_speck_context *ctx); 51 | 52 | int lw_speck_setkey(lw_speck_context *ctx, const uint8_t *key, uint16_t key_bitlen); 53 | 54 | void Speck_Encrypt_32(uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 55 | uint8_t *ciphertext); 56 | 57 | void Speck_Encrypt_48(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 58 | uint8_t *ciphertext); 59 | 60 | void Speck_Encrypt_64(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 61 | uint8_t *ciphertext); 62 | 63 | void Speck_Encrypt_96(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 64 | uint8_t *ciphertext); 65 | 66 | void Speck_Encrypt_128(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 67 | uint8_t *ciphertext); 68 | 69 | void Speck_Decrypt_32(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 70 | uint8_t *plaintext); 71 | 72 | void Speck_Decrypt_48(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 73 | uint8_t *plaintext); 74 | 75 | void Speck_Decrypt_64(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 76 | uint8_t *plaintext); 77 | 78 | void Speck_Decrypt_96(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 79 | uint8_t *plaintext); 80 | 81 | void Speck_Decrypt_128(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 82 | uint8_t *plaintext); 83 | 84 | int lw_speck_crypt_ecb(lw_speck_context *ctx, int mode, const uint8_t input[8], 85 | uint8_t output[8]); 86 | 87 | int lw_speck_crypt_cbc(lw_speck_context *ctx, int mode, size_t length, 88 | uint8_t iv[8], const uint8_t *input, uint8_t *output); 89 | 90 | int lw_speck_crypt_ctr(lw_speck_context *ctx, size_t length, uint8_t *nc_off, 91 | uint8_t nonce_counter[8], uint8_t stream_block[8], 92 | const uint8_t *input, uint8_t *output); 93 | 94 | int lw_speck_self_test(int verbose); 95 | 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | 100 | #endif //LWCIPHER_SPECK_H 101 | -------------------------------------------------------------------------------- /include/xtea.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @file xtea.h 3 | * 4 | * @brief This file includes the API declaration for the XTEA block cipher. 5 | * 6 | * In cryptography, XTEA (eXtended TEA) is a block cipher designed to 7 | * correct weaknesses in TEA. The cipher's designers were David Wheeler 8 | * and Roger Needham of the Cambridge Computer Laboratory, and the 9 | * algorithm was presented in an unpublished technical report in 1997 10 | * (Needham and Wheeler, 1997). The cipher has a 64-bit block size and 11 | * a 128-bit key size. 12 | * 13 | * The original paper you can find in the following link: 14 | * https://www.cl.cam.ac.uk/ftp/users/djw3/xtea.ps 15 | * 16 | * */ 17 | 18 | 19 | #ifndef LWCIPHER_XTEA_H 20 | #define LWCIPHER_XTEA_H 21 | 22 | #include 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* 30 | * @struct lw_xtea_context 31 | * @brief Structure for the XTEA context, the key is stored into for WORDS(32 bits) to adjust the algorithm. 32 | * */ 33 | typedef struct lw_xtea_context { 34 | uint32_t key[4]; 35 | } lw_xtea_context; 36 | 37 | #define XTEA_ENCRYPT 1 38 | #define XTEA_DECRYPT 0 39 | 40 | #define LW_ERR_ERROR_CORRUPTION_DETECTED (-0x000E) /**< Corrupted data detected. */ 41 | #define LW_ERR_XTEA_BAD_INPUT_DATA (-0x0010) /**< Bad input parameters to function. */ 42 | #define LW_ERR_XTEA_INVALID_INPUT_LENGTH (-0x0011) /**< Invalid data input length. */ 43 | 44 | /* 45 | * @brief This function initializes the XTEA context in order to use the XTEA algorithm. 46 | * In the implementation, it is memset(ctx, 0, sizeof(lw_xtea_context)). 47 | * @param ctx: pointer to a lw_xtea_context structure. 48 | * @retval None 49 | * */ 50 | void lw_xtea_init(lw_xtea_context *ctx); 51 | 52 | /* 53 | * @brief This function free the XTEA context in order to use the XTEA algorithm. 54 | * In the implementation, it is memset(ctx, 0, sizeof(lw_xtea_context)). 55 | * @param ctx: pointer to a lw_xtea_context structure. 56 | * @retval None 57 | * */ 58 | void lw_xtea_free(lw_xtea_context *ctx); 59 | 60 | /* 61 | * @brief This function set the key for the XTEA algorithm, using memcpy. 62 | * @param ctx: pointer to a lw_xtea_context structure. 63 | * @param key: pointer to the key. 64 | * @param key_bitlen: bit length of the key. 65 | * @retval 0 if the key is set correctly, -1 otherwise. 66 | * */ 67 | int lw_xtea_setkey(lw_xtea_context *ctx, const uint8_t key[16], unsigned int key_bitlen); 68 | 69 | /* 70 | * @brief This function encrypts or decrypts a block of 8 bytes with XTEA algorithm. 71 | * @param ctx: pointer to a lw_xtea_context structure. 72 | * @param mode: XTEA_ENCRYPT or XTEA_DECRYPT. 73 | * @param input: pointer to the input data. 74 | * @param output: pointer to the output data. 75 | * @retval 0 if the block is encrypted or decrypted correctly, -1 otherwise. 76 | * */ 77 | int lw_xtea_crypt_ecb(lw_xtea_context *ctx, int mode, const uint8_t input[8], 78 | uint8_t output[8]); 79 | 80 | /* 81 | * @brief This function encrypts or decrypts a block of 8 bytes with XTEA algorithm in CBC mode. 82 | * @param ctx: pointer to a lw_xtea_context structure. 83 | * @param mode: XTEA_ENCRYPT or XTEA_DECRYPT. 84 | * @param length: length of the input data. 85 | * @param iv: initialization vector. 86 | * @param input: pointer to the input data. 87 | * @param output: pointer to the output data. 88 | * @retval 0 if the block is encrypted or decrypted correctly, -1 otherwise. 89 | */ 90 | int lw_xtea_crypt_cbc(lw_xtea_context *ctx, int mode, size_t length, 91 | uint8_t iv[8], const uint8_t *input, uint8_t *output); 92 | 93 | int lw_xtea_crypt_ctr(lw_xtea_context *ctx, size_t length, uint8_t *nc_off, 94 | uint8_t nonce_counter[8], uint8_t stream_block[8], 95 | const uint8_t *input, uint8_t *output); 96 | 97 | int lw_xtea_self_test(int verbose); 98 | 99 | #ifdef __cplusplus 100 | } 101 | #endif 102 | 103 | #endif //LWCIPHER_XTEA_H 104 | -------------------------------------------------------------------------------- /include/xxtea.h: -------------------------------------------------------------------------------- 1 | #ifndef LWCIPHER_XXTEA_H 2 | #define LWCIPHER_XXTEA_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct lw_xxtea_context 12 | { 13 | uint32_t key[4]; 14 | } lw_xxtea_context; 15 | 16 | #define XXTEA_ENCRYPT 1 17 | #define XXTEA_DECRYPT 0 18 | 19 | #define LW_ERR_ERROR_CORRUPTION_DETECTED (-0x000E) /**< Corrupted data detected. */ 20 | #define LW_ERR_XXTEA_BAD_INPUT_DATA (-0x0020) /**< Bad input parameters to function. */ 21 | #define LW_ERR_XXTEA_INVALID_INPUT_LENGTH (-0x0021) /**< Invalid data input length. */ 22 | void lw_xxtea_init(lw_xxtea_context *ctx); 23 | 24 | void lw_xxtea_free(lw_xxtea_context *ctx); 25 | 26 | int lw_xxtea_setkey(lw_xxtea_context *ctx, const uint8_t key[16], unsigned int key_bitlen); 27 | 28 | int lw_xxtea_crypt_ecb(lw_xxtea_context *ctx, int mode, const uint8_t input[8], 29 | uint8_t output[8]); 30 | 31 | int lw_xxtea_crypt_cbc(lw_xxtea_context *ctx, int mode, size_t length, 32 | uint8_t iv[8], const uint8_t *input, uint8_t *output); 33 | 34 | int lw_xxtea_crypt_ctr(lw_xxtea_context *ctx, size_t length, uint8_t *nc_off, 35 | uint8_t nonce_counter[8], uint8_t stream_block[8], 36 | const uint8_t *input, uint8_t *output); 37 | 38 | int lw_xxtea_self_test(int verbose); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif //LWCIPHER_XXTEA_H 45 | -------------------------------------------------------------------------------- /internal/lw_cipher_wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef LWCIPHER_LW_CIPHER_WRAPPER_H 2 | #define LWCIPHER_LW_CIPHER_WRAPPER_H 3 | #include "lwcipher.h" 4 | typedef struct lw_cipher_base_t { 5 | lw_cipher_id_t cipher; 6 | int (*ecb_func)(void *ctx,lw_operation_t mode, 7 | const uint8_t *input, uint8_t *output); 8 | int (*cbc_func)(void *ctx,lw_operation_t mode, size_t length, 9 | uint8_t *iv,const uint8_t *input, uint8_t *output); 10 | int (*ctr_func)(void *ctx,size_t length,uint8_t *nc_off, 11 | uint8_t *nonce_counter,uint8_t *stream_block, 12 | const uint8_t *input, uint8_t *output); 13 | int (*setkey_enc_func)(void *ctx,const uint8_t *key, 14 | unsigned int key_bitlen); 15 | int (*setkey_dec_func)(void *ctx,const uint8_t *key, 16 | unsigned int key_bitlen); 17 | /** Allocate a new context */ 18 | void * (*ctx_alloc_func)(uint8_t block_size); 19 | 20 | /** Free the given context */ 21 | void (*ctx_free_func)(void *ctx); 22 | }lw_cipher_base_t; 23 | 24 | typedef struct { 25 | lw_cipher_type_t type; 26 | const lw_cipher_info_t *info; 27 | }lw_cipher_definition_t; 28 | 29 | extern const lw_cipher_definition_t lw_cipher_definitions[]; 30 | 31 | extern const lw_cipher_base_t *lw_cipher_base_lookup_table[]; 32 | 33 | #endif //LWCIPHER_LW_CIPHER_WRAPPER_H 34 | -------------------------------------------------------------------------------- /src/lw_cipher.c: -------------------------------------------------------------------------------- 1 | #include "lwcipher.h" 2 | #include "lw_cipher_wrapper.h" 3 | #include 4 | #include 5 | 6 | static inline const lw_cipher_base_t *lw_cipher_get_base(const lw_cipher_info_t *info) 7 | { 8 | return lw_cipher_base_lookup_table[info->base_idx]; 9 | } 10 | 11 | const lw_cipher_info_t *lw_cipher_info_from_type(const lw_cipher_type_t cipher_type) 12 | { 13 | const lw_cipher_definition_t *def; 14 | 15 | for (def = lw_cipher_definitions; def->info != NULL; def++) { 16 | if (def->type == cipher_type) { 17 | return def->info; 18 | } 19 | } 20 | return NULL; 21 | } 22 | 23 | const lw_cipher_info_t *lw_cipher_info_from_string(const char *cipher_name) 24 | { 25 | const lw_cipher_definition_t *def; 26 | if (NULL == cipher_name) { 27 | return NULL; 28 | } 29 | 30 | for (def = lw_cipher_definitions; def->info != NULL; def++) { 31 | if (!strcmp(def->info->name, cipher_name)) { 32 | return def->info; 33 | } 34 | } 35 | return NULL; 36 | } 37 | 38 | const lw_cipher_info_t * 39 | lw_cipher_info_from_values(const lw_cipher_id_t cipher_id, int key_bitlen, const lw_cipher_mode_t cipher_mode) 40 | { 41 | const lw_cipher_definition_t *def; 42 | 43 | for (def = lw_cipher_definitions; def->info != NULL; def++) { 44 | if (lw_cipher_get_base(def->info)->cipher == cipher_id && 45 | lw_cipher_info_get_key_bitlen((lw_cipher_info_t *)(def->info)) == (unsigned) key_bitlen && 46 | def->info->mode == cipher_mode) { 47 | return def->info; 48 | } 49 | } 50 | return NULL; 51 | } 52 | 53 | void lw_cipher_init(lw_cipher_context_t *ctx) 54 | { 55 | memset(ctx, 0, sizeof(lw_cipher_context_t)); 56 | ctx->cipher_info = (lw_cipher_info_t*) malloc(sizeof(lw_cipher_info_t)); 57 | } 58 | 59 | void lw_cipher_free(lw_cipher_context_t *ctx) 60 | { 61 | if (ctx == NULL) { 62 | return; 63 | } 64 | if (ctx->cipher_ctx) { 65 | lw_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx); 66 | } 67 | free(ctx->cipher_info); 68 | ctx->cipher_info = NULL; 69 | memset(ctx, 0, sizeof(lw_cipher_context_t)); 70 | } 71 | 72 | int lw_cipher_setup(lw_cipher_context_t *ctx, const lw_cipher_info_t *cipher_info) 73 | { 74 | if (cipher_info == NULL) { 75 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 76 | } 77 | 78 | if (NULL == (ctx->cipher_ctx = lw_cipher_get_base(cipher_info)->ctx_alloc_func(cipher_info->block_size))) { 79 | return LW_ERR_CIPHER_ALLOC_FAILED; 80 | } 81 | memcpy(ctx->cipher_info, cipher_info, sizeof(lw_cipher_info_t)) ; 82 | return 0; 83 | } 84 | 85 | int lw_cipher_setkey(lw_cipher_context_t *ctx, const uint8_t *key, unsigned int key_bitlen, 86 | const lw_operation_t operation) 87 | { 88 | if (operation != LW_ENCRYPT && operation != LW_DECRYPT) { 89 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 90 | } 91 | if (ctx->cipher_info == NULL) { 92 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 93 | } 94 | 95 | ctx->key_bitlen = key_bitlen; 96 | ctx->operation = operation; 97 | 98 | if (operation == LW_ENCRYPT || LW_MODE_CTR == ((lw_cipher_mode_t) ctx->cipher_info->mode)) 99 | return lw_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key, 100 | ctx->key_bitlen); 101 | if (LW_DECRYPT == operation) { 102 | return lw_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key, 103 | ctx->key_bitlen); 104 | } 105 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 106 | } 107 | 108 | int lw_cipher_set_iv(lw_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len) 109 | { 110 | uint16_t actual_iv_size; 111 | if (ctx->cipher_info == NULL) { 112 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 113 | } 114 | /* avoid buffer overflow in ctx->iv */ 115 | if (iv_len > LW_MAX_IV_LENGTH) { 116 | return LW_ERR_CIPHER_FEATURE_UNAVAILABLE; 117 | } 118 | lw_cipher_info_get_iv_size(ctx->cipher_info); 119 | actual_iv_size = lw_cipher_info_get_iv_size(ctx->cipher_info); 120 | /* avoid reading past the end of input buffer */ 121 | if (actual_iv_size > iv_len) { 122 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 123 | } 124 | 125 | if (actual_iv_size != 0) { 126 | memcpy(ctx->iv, iv, actual_iv_size); 127 | ctx->iv_size = actual_iv_size; 128 | } 129 | return 0; 130 | } 131 | 132 | int lw_cipher_reset(lw_cipher_context_t *ctx) 133 | { 134 | if (ctx->cipher_info == NULL) { 135 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 136 | } 137 | ctx->unprocessed_len = 0; 138 | return 0; 139 | } 140 | 141 | int lw_cipher_update(lw_cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, 142 | size_t *olen) 143 | { 144 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 145 | size_t block_size; 146 | 147 | if (ctx->cipher_info == NULL) { 148 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 149 | } 150 | 151 | *olen = 0; 152 | block_size = lw_cipher_get_block_size(ctx); 153 | if (0 == block_size) { 154 | return LW_ERR_CIPHER_INVALID_CONTEXT; 155 | } 156 | 157 | if (((lw_cipher_mode_t) ctx->cipher_info->mode) == LW_MODE_ECB) { 158 | if (ilen != block_size) { 159 | return LW_ERR_CIPHER_FULL_BLOCK_EXPECTED; 160 | } 161 | *olen = ilen; 162 | if (0 != (ret = lw_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx, 163 | ctx->operation, input, 164 | output))) { 165 | return ret; 166 | } 167 | return 0; 168 | } 169 | 170 | 171 | if (input == output && 172 | (ctx->unprocessed_len != 0 || ilen % block_size)) { 173 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 174 | } 175 | 176 | if (((lw_cipher_mode_t) ctx->cipher_info->mode) == LW_MODE_CBC) { 177 | int copy_len = 0; 178 | /* 179 | * If there is not enough data for a full block, cache it. 180 | */ 181 | if ((ctx->operation == LW_DECRYPT && NULL != ctx->add_padding && 182 | ilen <= block_size - ctx->unprocessed_len) || 183 | (ctx->operation == LW_DECRYPT && NULL == ctx->add_padding && 184 | ilen < block_size - ctx->unprocessed_len) || 185 | (ctx->operation == LW_ENCRYPT && 186 | ilen < block_size - ctx->unprocessed_len)) { 187 | memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, 188 | ilen); 189 | ctx->unprocessed_len += ilen; 190 | return 0; 191 | } 192 | 193 | /* 194 | * Process cached data first 195 | */ 196 | if (0 != ctx->unprocessed_len) { 197 | copy_len = block_size - ctx->unprocessed_len; 198 | 199 | memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, 200 | copy_len); 201 | 202 | if (0 != (ret = lw_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, 203 | ctx->operation, 204 | block_size, ctx->iv, 205 | ctx->unprocessed_data, 206 | output))) { 207 | return ret; 208 | } 209 | *olen += block_size; 210 | output += block_size; 211 | ctx->unprocessed_len = 0; 212 | input += copy_len; 213 | ilen -= copy_len; 214 | } 215 | /* 216 | * Cache final, incomplete block 217 | */ 218 | if (0 != ilen) { 219 | /* Encryption: only cache partial blocks 220 | * Decryption w/ padding: always keep at least one whole block 221 | * Decryption w/o padding: only cache partial blocks 222 | */ 223 | copy_len = ilen % block_size; 224 | if (copy_len == 0 && 225 | ctx->operation == LW_DECRYPT && 226 | NULL != ctx->add_padding) { 227 | copy_len = block_size; 228 | } 229 | 230 | memcpy(ctx->unprocessed_data, &(input[ilen - copy_len]), 231 | copy_len); 232 | 233 | ctx->unprocessed_len += copy_len; 234 | ilen -= copy_len; 235 | } 236 | 237 | /* 238 | * Process remaining full blocks 239 | */ 240 | if (ilen) { 241 | if (0 != (ret = lw_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, 242 | ctx->operation, 243 | ilen, ctx->iv, 244 | input, 245 | output))) { 246 | return ret; 247 | } 248 | 249 | *olen += ilen; 250 | } 251 | } 252 | if (((lw_cipher_mode_t) ctx->cipher_info->mode) == LW_MODE_CTR) { 253 | if (0 != (ret = lw_cipher_get_base(ctx->cipher_info)->ctr_func(ctx->cipher_ctx, 254 | ilen, 255 | (uint8_t *) &ctx->unprocessed_len, 256 | ctx->iv, 257 | ctx->unprocessed_data, 258 | input, output))) { 259 | return ret; 260 | } 261 | *olen = ilen; 262 | return 0; 263 | } 264 | return 0; 265 | } 266 | 267 | 268 | int lw_cipher_finish(lw_cipher_context_t *ctx, unsigned char *output, size_t *olen) 269 | { 270 | if (ctx->cipher_info == NULL) { 271 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 272 | } 273 | *olen = 0; 274 | if (LW_MODE_CTR == ((lw_cipher_mode_t) ctx->cipher_info->mode)) { 275 | return 0; 276 | } 277 | if (LW_MODE_ECB == ((lw_cipher_mode_t) ctx->cipher_info->mode)) { 278 | if (ctx->unprocessed_len != 0) { 279 | return LW_ERR_CIPHER_FULL_BLOCK_EXPECTED; 280 | } 281 | return 0; 282 | } 283 | if (LW_MODE_CBC == ((lw_cipher_mode_t) ctx->cipher_info->mode)) { 284 | int ret = 0; 285 | 286 | if (LW_ENCRYPT == ctx->operation) { 287 | /* check for 'no padding' mode */ 288 | if (NULL == ctx->add_padding) { 289 | if (0 != ctx->unprocessed_len) { 290 | return LW_ERR_CIPHER_FULL_BLOCK_EXPECTED; 291 | } 292 | return 0; 293 | } 294 | 295 | ctx->add_padding(ctx->unprocessed_data, lw_cipher_get_iv_size(ctx), 296 | ctx->unprocessed_len); 297 | } else if (lw_cipher_get_block_size(ctx) != ctx->unprocessed_len) { 298 | /* 299 | * For decrypt operations, expect a full block, 300 | * or an empty block if no padding 301 | */ 302 | if (NULL == ctx->add_padding && 0 == ctx->unprocessed_len) { 303 | return 0; 304 | } 305 | return LW_ERR_CIPHER_FULL_BLOCK_EXPECTED; 306 | } 307 | 308 | /* cipher block */ 309 | if (0 != (ret = lw_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, 310 | ctx->operation, 311 | lw_cipher_get_block_size( 312 | ctx), 313 | ctx->iv, 314 | ctx->unprocessed_data, 315 | output))) { 316 | return ret; 317 | } 318 | /* Set output size for decryption */ 319 | if (LW_DECRYPT == ctx->operation) { 320 | return ctx->get_padding(output, lw_cipher_get_block_size(ctx), 321 | olen); 322 | } 323 | /* Set output size for encryption */ 324 | *olen = lw_cipher_get_block_size(ctx); 325 | return 0; 326 | } 327 | return LW_ERR_CIPHER_FEATURE_UNAVAILABLE; 328 | } 329 | 330 | /* 331 | * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len 332 | */ 333 | static void add_pkcs_padding(unsigned char *output, size_t output_len, 334 | size_t data_len) 335 | { 336 | size_t padding_len = output_len - data_len; 337 | unsigned char i; 338 | 339 | for (i = 0; i < padding_len; i++) { 340 | output[data_len + i] = (unsigned char) padding_len; 341 | } 342 | } 343 | 344 | static int get_pkcs_padding(unsigned char *input, size_t input_len, 345 | size_t *data_len) 346 | { 347 | size_t i, pad_idx; 348 | unsigned char padding_len; 349 | 350 | if (NULL == input || NULL == data_len) { 351 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 352 | } 353 | 354 | padding_len = input[input_len - 1]; 355 | *data_len = input_len - padding_len; 356 | 357 | size_t bad = padding_len > input_len; 358 | bad = (bad | (padding_len == 0)); 359 | 360 | /* The number of bytes checked must be independent of padding_len, 361 | * so pick input_len, which is usually 8 or 16 (one block) */ 362 | pad_idx = input_len - padding_len; 363 | for (i = 0; i < input_len; i++) { 364 | size_t in_padding = (i >= pad_idx); 365 | size_t different = (input[i] != padding_len); 366 | bad = (bad | (in_padding & different)); 367 | } 368 | return -((int) (bad & (-LW_ERR_CIPHER_INVALID_PADDING))); 369 | } 370 | 371 | /* 372 | * No padding: don't pad :) 373 | * 374 | * There is no add_padding function (check for NULL in lw_cipher_finish) 375 | * but a trivial get_padding function 376 | */ 377 | static int get_no_padding(unsigned char *input, size_t input_len, 378 | size_t *data_len) 379 | { 380 | if (NULL == input || NULL == data_len) { 381 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 382 | } 383 | 384 | *data_len = input_len; 385 | 386 | return 0; 387 | } 388 | 389 | int lw_cipher_set_padding_mode(lw_cipher_context_t *ctx, lw_cipher_padding_t mode) 390 | { 391 | if (NULL == ctx->cipher_info || 392 | LW_MODE_CBC != ((lw_cipher_mode_t) ctx->cipher_info->mode)) { 393 | return LW_ERR_CIPHER_BAD_INPUT_DATA; 394 | } 395 | switch (mode) { 396 | case LW_CIPHER_PADDING_PKCS7: 397 | ctx->add_padding = add_pkcs_padding; 398 | ctx->get_padding = get_pkcs_padding; 399 | break; 400 | case LW_CIPHER_PADDING_NONE: 401 | ctx->add_padding = NULL; 402 | ctx->get_padding = get_no_padding; 403 | break; 404 | default: 405 | return LW_ERR_CIPHER_FEATURE_UNAVAILABLE; 406 | } 407 | return 0; 408 | } 409 | 410 | int lw_cipher_crypt(lw_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, const unsigned char *input, 411 | size_t ilen, unsigned char *output, size_t *olen) 412 | { 413 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 414 | size_t finish_olen; 415 | 416 | if ((ret = lw_cipher_set_iv(ctx, iv, iv_len)) != 0) { 417 | return ret; 418 | } 419 | 420 | if ((ret = lw_cipher_reset(ctx)) != 0) { 421 | return ret; 422 | } 423 | 424 | if ((ret = lw_cipher_update(ctx, input, ilen, 425 | output, olen)) != 0) { 426 | return ret; 427 | } 428 | 429 | if ((ret = lw_cipher_finish(ctx, output + *olen, 430 | &finish_olen)) != 0) { 431 | return ret; 432 | } 433 | 434 | *olen += finish_olen; 435 | 436 | return 0; 437 | } 438 | -------------------------------------------------------------------------------- /src/lw_cipher_wrapper.c: -------------------------------------------------------------------------------- 1 | #include "lw_cipher_wrapper.h" 2 | #include "lwcipher.h" 3 | #include 4 | 5 | enum lw_cipher_base_index 6 | { 7 | LW_CIPHER_BASE_INDEX_XTEA, 8 | LW_CIPHER_BASE_INDEX_XXTEA, 9 | LW_CIPHER_BASE_INDEX_SIMON, 10 | LW_CIPHER_BASE_INDEX_SPECK, 11 | LW_CIPHER_BASE_INDEX_PRESENT 12 | }; 13 | 14 | static int xtea_crypt_ecb_wrap(void *ctx, lw_operation_t operation, 15 | const uint8_t *input, uint8_t *output) 16 | { 17 | return lw_xtea_crypt_ecb((lw_xtea_context *) ctx, operation, input, output); 18 | } 19 | 20 | static int xtea_crypt_cbc_wrap(void *ctx, lw_operation_t operation, 21 | size_t length, uint8_t *iv, 22 | const uint8_t *input, uint8_t *output) 23 | { 24 | return lw_xtea_crypt_cbc((lw_xtea_context *) ctx, operation, length, iv, 25 | input, output); 26 | } 27 | 28 | static int xtea_crypt_ctr_wrap(void *ctx, size_t length, uint8_t *nc_off, 29 | uint8_t *nonce_counter, 30 | uint8_t *stream_block, const uint8_t *input, 31 | uint8_t *output) 32 | { 33 | return lw_xtea_crypt_ctr((lw_xtea_context *) ctx, length, nc_off, 34 | nonce_counter, stream_block, input, output); 35 | } 36 | 37 | static int xtea_setkey_enc_wrap(void *ctx, const uint8_t *key, 38 | unsigned int key_bitlen) 39 | { 40 | return lw_xtea_setkey((lw_xtea_context *) ctx, key, key_bitlen); 41 | } 42 | 43 | static int xtea_setkey_dec_wrap(void *ctx, const uint8_t *key, 44 | unsigned int key_bitlen) 45 | { 46 | return lw_xtea_setkey((lw_xtea_context *) ctx, key, key_bitlen); 47 | } 48 | 49 | static void *xtea_ctx_alloc(uint8_t para) 50 | { 51 | lw_xtea_context *ctx = (lw_xtea_context *) malloc(sizeof(lw_xtea_context)); 52 | if (ctx == NULL) { 53 | return NULL; 54 | } 55 | lw_xtea_init(ctx); 56 | return ctx; 57 | } 58 | 59 | static void xtea_ctx_free(void *ctx) 60 | { 61 | lw_xtea_free((lw_xtea_context *) ctx); 62 | free(ctx); 63 | } 64 | 65 | static const lw_cipher_base_t xtea_info = { 66 | LW_CIPHER_ID_XTEA, 67 | xtea_crypt_ecb_wrap, 68 | xtea_crypt_cbc_wrap, 69 | xtea_crypt_ctr_wrap, 70 | xtea_setkey_enc_wrap, 71 | xtea_setkey_dec_wrap, 72 | xtea_ctx_alloc, 73 | xtea_ctx_free 74 | }; 75 | 76 | static const lw_cipher_info_t lw_cipher_xtea_ecb_info = { 77 | "XTEA-ECB", 78 | 8, 79 | 0, 80 | 128, 81 | LW_MODE_ECB, 82 | LW_CIPHER_XTEA_ECB, 83 | 0, 84 | LW_CIPHER_BASE_INDEX_XTEA 85 | }; 86 | 87 | static const lw_cipher_info_t lw_cipher_xtea_cbc_info = { 88 | "XTEA-CBC", 89 | 8, 90 | 8, 91 | 128, 92 | LW_MODE_CBC, 93 | LW_CIPHER_XTEA_CBC, 94 | 0, 95 | LW_CIPHER_BASE_INDEX_XTEA 96 | }; 97 | 98 | static const lw_cipher_info_t lw_cipher_xtea_ctr_info = { 99 | "XTEA-CTR", 100 | 8, 101 | 8, 102 | 128, 103 | LW_MODE_CTR, 104 | LW_CIPHER_XTEA_CTR, 105 | 0, 106 | LW_CIPHER_BASE_INDEX_XTEA 107 | }; 108 | 109 | static int xxtea_crypt_ecb_wrap(void *ctx, lw_operation_t operation, 110 | const uint8_t *input, uint8_t *output) 111 | { 112 | return lw_xxtea_crypt_ecb((lw_xxtea_context *) ctx, operation, input, 113 | output); 114 | } 115 | 116 | static int xxtea_crypt_cbc_wrap(void *ctx, lw_operation_t operation, 117 | size_t length, uint8_t *iv, 118 | const uint8_t *input, uint8_t *output) 119 | { 120 | return lw_xxtea_crypt_cbc((lw_xxtea_context *) ctx, operation, length, iv, 121 | input, output); 122 | } 123 | 124 | static int xxtea_crypt_ctr_wrap(void *ctx, size_t length, uint8_t *nc_off, 125 | uint8_t *nonce_counter, 126 | uint8_t *stream_block, const uint8_t *input, 127 | uint8_t *output) 128 | { 129 | return lw_xxtea_crypt_ctr((lw_xxtea_context *) ctx, length, nc_off, 130 | nonce_counter, stream_block, input, output); 131 | } 132 | 133 | static int xxtea_setkey_enc_wrap(void *ctx, const uint8_t *key, 134 | unsigned int key_bitlen) 135 | { 136 | return lw_xxtea_setkey((lw_xxtea_context *) ctx, key, key_bitlen); 137 | } 138 | 139 | static int xxtea_setkey_dec_wrap(void *ctx, const uint8_t *key, 140 | unsigned int key_bitlen) 141 | { 142 | return lw_xxtea_setkey((lw_xxtea_context *) ctx, key, key_bitlen); 143 | } 144 | 145 | static void *xxtea_ctx_alloc(uint8_t para) 146 | { 147 | lw_xxtea_context *ctx = (lw_xxtea_context *) malloc( 148 | sizeof(lw_xxtea_context)); 149 | if (ctx == NULL) { 150 | return NULL; 151 | } 152 | lw_xxtea_init(ctx); 153 | return ctx; 154 | } 155 | 156 | static void xxtea_ctx_free(void *ctx) 157 | { 158 | lw_xxtea_free((lw_xxtea_context *) ctx); 159 | free(ctx); 160 | } 161 | 162 | static const lw_cipher_base_t xxtea_info = { 163 | LW_CIPHER_ID_XXTEA, 164 | xxtea_crypt_ecb_wrap, 165 | xxtea_crypt_cbc_wrap, 166 | xxtea_crypt_ctr_wrap, 167 | xxtea_setkey_enc_wrap, 168 | xxtea_setkey_dec_wrap, 169 | xxtea_ctx_alloc, 170 | xxtea_ctx_free 171 | }; 172 | 173 | static const lw_cipher_info_t lw_cipher_xxtea_ecb_info = { 174 | "XXTEA-ECB", 175 | 8, 176 | 0, 177 | 128, 178 | LW_MODE_ECB, 179 | LW_CIPHER_XXTEA_ECB, 180 | 0, 181 | LW_CIPHER_BASE_INDEX_XXTEA 182 | }; 183 | 184 | static const lw_cipher_info_t lw_cipher_xxtea_cbc_info = { 185 | "XXTEA-CBC", 186 | 8, 187 | 8, 188 | 128, 189 | LW_MODE_CBC, 190 | LW_CIPHER_XXTEA_CBC, 191 | 0, 192 | LW_CIPHER_BASE_INDEX_XXTEA 193 | }; 194 | 195 | static const lw_cipher_info_t lw_cipher_xxtea_ctr_info = { 196 | "XXTEA-CTR", 197 | 8, 198 | 8, 199 | 128, 200 | LW_MODE_CTR, 201 | LW_CIPHER_XXTEA_CTR, 202 | 0, 203 | LW_CIPHER_BASE_INDEX_XXTEA 204 | }; 205 | 206 | static int simon_crypt_ecb_wrap(void *ctx, lw_operation_t operation, 207 | const uint8_t *input, uint8_t *output) 208 | { 209 | return lw_simon_crypt_ecb((lw_simon_context *) ctx, operation, input, 210 | output); 211 | } 212 | 213 | static int simon_crypt_cbc_wrap(void *ctx, lw_operation_t operation, 214 | size_t length, uint8_t *iv, 215 | const uint8_t *input, uint8_t *output) 216 | { 217 | return lw_simon_crypt_cbc((lw_simon_context *) ctx, operation, length, iv, 218 | input, output); 219 | } 220 | 221 | static int simon_crypt_ctr_wrap(void *ctx, size_t length, uint8_t *nc_off, 222 | uint8_t *nonce_counter, 223 | uint8_t *stream_block, const uint8_t *input, 224 | uint8_t *output) 225 | { 226 | return lw_simon_crypt_ctr((lw_simon_context *) ctx, length, nc_off, 227 | nonce_counter, stream_block, input, output); 228 | } 229 | 230 | static int simon_setkey_enc_wrap(void *ctx, const uint8_t *key, 231 | unsigned int key_bitlen) 232 | { 233 | return lw_simon_setkey((lw_simon_context *) ctx, key, key_bitlen); 234 | } 235 | 236 | static int simon_setkey_dec_wrap(void *ctx, const uint8_t *key, 237 | unsigned int key_bitlen) 238 | { 239 | return lw_simon_setkey((lw_simon_context *) ctx, key, key_bitlen); 240 | } 241 | 242 | static void *simon_ctx_alloc(uint8_t block_size) 243 | { 244 | lw_simon_context *ctx = (lw_simon_context *) malloc( 245 | sizeof(lw_simon_context)); 246 | if (ctx == NULL) { 247 | return NULL; 248 | } 249 | lw_simon_init(ctx, block_size); 250 | return ctx; 251 | } 252 | 253 | static void simon_ctx_free(void *ctx) 254 | { 255 | lw_simon_free((lw_simon_context *) ctx); 256 | free(ctx); 257 | } 258 | 259 | static const lw_cipher_base_t simon_info = { 260 | LW_CIPHER_ID_SIMON, 261 | simon_crypt_ecb_wrap, 262 | simon_crypt_cbc_wrap, 263 | simon_crypt_ctr_wrap, 264 | simon_setkey_enc_wrap, 265 | simon_setkey_dec_wrap, 266 | simon_ctx_alloc, 267 | simon_ctx_free 268 | }; 269 | 270 | static const lw_cipher_info_t lw_cipher_simon_64_32_ecb_info = { 271 | "SIMON-64_32-ECB", 272 | 4, 273 | 0, 274 | 64, 275 | LW_MODE_ECB, 276 | LW_CIPHER_SIMON_64_32_ECB, 277 | 0, 278 | LW_CIPHER_BASE_INDEX_SIMON 279 | }; 280 | 281 | static const lw_cipher_info_t lw_cipher_simon_64_32_cbc_info = { 282 | "SIMON-64_32-CBC", 283 | 4, 284 | 4, 285 | 64, 286 | LW_MODE_CBC, 287 | LW_CIPHER_SIMON_64_32_CBC, 288 | 0, 289 | LW_CIPHER_BASE_INDEX_SIMON 290 | }; 291 | 292 | static const lw_cipher_info_t lw_cipher_simon_64_32_ctr_info = { 293 | "SIMON-64_32-CTR", 294 | 4, 295 | 4, 296 | 64, 297 | LW_MODE_CTR, 298 | LW_CIPHER_SIMON_64_32_CTR, 299 | 0, 300 | LW_CIPHER_BASE_INDEX_SIMON 301 | }; 302 | 303 | static const lw_cipher_info_t lw_cipher_simon_72_48_ecb_info = { 304 | "SIMON-72_48-ECB", 305 | 6, 306 | 0, 307 | 72, 308 | LW_MODE_ECB, 309 | LW_CIPHER_SIMON_72_48_ECB, 310 | 0, 311 | LW_CIPHER_BASE_INDEX_SIMON 312 | }; 313 | 314 | static const lw_cipher_info_t lw_cipher_simon_72_48_cbc_info = { 315 | "SIMON-72_48-CBC", 316 | 6, 317 | 6, 318 | 72, 319 | LW_MODE_CBC, 320 | LW_CIPHER_SIMON_72_48_CBC, 321 | 0, 322 | LW_CIPHER_BASE_INDEX_SIMON 323 | }; 324 | 325 | static const lw_cipher_info_t lw_cipher_simon_72_48_ctr_info = { 326 | "SIMON-72_48-CTR", 327 | 6, 328 | 6, 329 | 72, 330 | LW_MODE_CTR, 331 | LW_CIPHER_SIMON_72_48_CTR, 332 | 0, 333 | LW_CIPHER_BASE_INDEX_SIMON 334 | }; 335 | 336 | static const lw_cipher_info_t lw_cipher_simon_96_48_ecb_info = { 337 | "SIMON-96_48-ECB", 338 | 6, 339 | 0, 340 | 96, 341 | LW_MODE_ECB, 342 | LW_CIPHER_SIMON_96_48_ECB, 343 | 0, 344 | LW_CIPHER_BASE_INDEX_SIMON 345 | }; 346 | 347 | static const lw_cipher_info_t lw_cipher_simon_96_48_cbc_info = { 348 | "SIMON-96_48-CBC", 349 | 6, 350 | 6, 351 | 96, 352 | LW_MODE_CBC, 353 | LW_CIPHER_SIMON_96_48_CBC, 354 | 0, 355 | LW_CIPHER_BASE_INDEX_SIMON 356 | }; 357 | 358 | static const lw_cipher_info_t lw_cipher_simon_96_48_ctr_info = { 359 | "SIMON-96_48-CTR", 360 | 6, 361 | 6, 362 | 96, 363 | LW_MODE_CTR, 364 | LW_CIPHER_SIMON_96_48_CTR, 365 | 0, 366 | LW_CIPHER_BASE_INDEX_SIMON 367 | }; 368 | 369 | static const lw_cipher_info_t lw_cipher_simon_96_64_ecb_info = { 370 | "SIMON-96_64-ECB", 371 | 8, 372 | 0, 373 | 96, 374 | LW_MODE_ECB, 375 | LW_CIPHER_SIMON_96_64_ECB, 376 | 0, 377 | LW_CIPHER_BASE_INDEX_SIMON 378 | }; 379 | 380 | static const lw_cipher_info_t lw_cipher_simon_96_64_cbc_info = { 381 | "SIMON-96_64-CBC", 382 | 8, 383 | 8, 384 | 96, 385 | LW_MODE_CBC, 386 | LW_CIPHER_SIMON_96_64_CBC, 387 | 0, 388 | LW_CIPHER_BASE_INDEX_SIMON 389 | }; 390 | 391 | static const lw_cipher_info_t lw_cipher_simon_96_64_ctr_info = { 392 | "SIMON-96_64-CTR", 393 | 8, 394 | 8, 395 | 96, 396 | LW_MODE_CTR, 397 | LW_CIPHER_SIMON_96_64_CTR, 398 | 0, 399 | LW_CIPHER_BASE_INDEX_SIMON 400 | }; 401 | 402 | static const lw_cipher_info_t lw_cipher_simon_128_64_ecb_info = { 403 | "SIMON-128_64-ECB", 404 | 8, 405 | 0, 406 | 128, 407 | LW_MODE_ECB, 408 | LW_CIPHER_SIMON_128_64_ECB, 409 | 0, 410 | LW_CIPHER_BASE_INDEX_SIMON 411 | }; 412 | 413 | static const lw_cipher_info_t lw_cipher_simon_128_64_cbc_info = { 414 | "SIMON-128_64-CBC", 415 | 8, 416 | 8, 417 | 128, 418 | LW_MODE_CBC, 419 | LW_CIPHER_SIMON_128_64_CBC, 420 | 0, 421 | LW_CIPHER_BASE_INDEX_SIMON 422 | }; 423 | 424 | static const lw_cipher_info_t lw_cipher_simon_128_64_ctr_info = { 425 | "SIMON-128_64-CTR", 426 | 8, 427 | 8, 428 | 128, 429 | LW_MODE_CTR, 430 | LW_CIPHER_SIMON_128_64_CTR, 431 | 0, 432 | LW_CIPHER_BASE_INDEX_SIMON 433 | }; 434 | 435 | static const lw_cipher_info_t lw_cipher_simon_96_96_ecb_info = { 436 | "SIMON-96_96-ECB", 437 | 12, 438 | 0, 439 | 96, 440 | LW_MODE_ECB, 441 | LW_CIPHER_SIMON_96_96_ECB, 442 | 0, 443 | LW_CIPHER_BASE_INDEX_SIMON 444 | }; 445 | 446 | static const lw_cipher_info_t lw_cipher_simon_96_96_cbc_info = { 447 | "SIMON-96_96-CBC", 448 | 12, 449 | 12, 450 | 96, 451 | LW_MODE_CBC, 452 | LW_CIPHER_SIMON_96_96_CBC, 453 | 0, 454 | LW_CIPHER_BASE_INDEX_SIMON 455 | }; 456 | 457 | static const lw_cipher_info_t lw_cipher_simon_96_96_ctr_info = { 458 | "SIMON-96_96-CTR", 459 | 12, 460 | 12, 461 | 96, 462 | LW_MODE_CTR, 463 | LW_CIPHER_SIMON_96_96_CTR, 464 | 0, 465 | LW_CIPHER_BASE_INDEX_SIMON 466 | }; 467 | 468 | static const lw_cipher_info_t lw_cipher_simon_144_96_ecb_info = { 469 | "SIMON-144_96-ECB", 470 | 12, 471 | 0, 472 | 144, 473 | LW_MODE_ECB, 474 | LW_CIPHER_SIMON_144_96_ECB, 475 | 0, 476 | LW_CIPHER_BASE_INDEX_SIMON 477 | }; 478 | 479 | static const lw_cipher_info_t lw_cipher_simon_144_96_cbc_info = { 480 | "SIMON-144_96-CBC", 481 | 12, 482 | 12, 483 | 144, 484 | LW_MODE_CBC, 485 | LW_CIPHER_SIMON_144_96_CBC, 486 | 0, 487 | LW_CIPHER_BASE_INDEX_SIMON 488 | }; 489 | 490 | static const lw_cipher_info_t lw_cipher_simon_144_96_ctr_info = { 491 | "SIMON-144_96-CTR", 492 | 12, 493 | 12, 494 | 144, 495 | LW_MODE_CTR, 496 | LW_CIPHER_SIMON_144_96_CTR, 497 | 0, 498 | LW_CIPHER_BASE_INDEX_SIMON 499 | }; 500 | 501 | static const lw_cipher_info_t lw_cipher_simon_128_128_ecb_info = { 502 | "SIMON-128_128-ECB", 503 | 16, 504 | 0, 505 | 128, 506 | LW_MODE_ECB, 507 | LW_CIPHER_SIMON_128_128_ECB, 508 | 0, 509 | LW_CIPHER_BASE_INDEX_SIMON 510 | }; 511 | 512 | static const lw_cipher_info_t lw_cipher_simon_128_128_cbc_info = { 513 | "SIMON-128_128-CBC", 514 | 16, 515 | 16, 516 | 128, 517 | LW_MODE_CBC, 518 | LW_CIPHER_SIMON_128_128_CBC, 519 | 0, 520 | LW_CIPHER_BASE_INDEX_SIMON 521 | }; 522 | 523 | static const lw_cipher_info_t lw_cipher_simon_128_128_ctr_info = { 524 | "SIMON-128_128-CTR", 525 | 16, 526 | 16, 527 | 128, 528 | LW_MODE_CTR, 529 | LW_CIPHER_SIMON_128_128_CTR, 530 | 0, 531 | LW_CIPHER_BASE_INDEX_SIMON 532 | }; 533 | 534 | static const lw_cipher_info_t lw_cipher_simon_192_128_ecb_info = { 535 | "SIMON-192_128-ECB", 536 | 16, 537 | 0, 538 | 192, 539 | LW_MODE_ECB, 540 | LW_CIPHER_SIMON_192_128_ECB, 541 | 0, 542 | LW_CIPHER_BASE_INDEX_SIMON 543 | }; 544 | 545 | static const lw_cipher_info_t lw_cipher_simon_192_128_cbc_info = { 546 | "SIMON-192_128-CBC", 547 | 16, 548 | 16, 549 | 192, 550 | LW_MODE_CBC, 551 | LW_CIPHER_SIMON_192_128_CBC, 552 | 0, 553 | LW_CIPHER_BASE_INDEX_SIMON 554 | }; 555 | 556 | static const lw_cipher_info_t lw_cipher_simon_192_128_ctr_info = { 557 | "SIMON-192_128-CTR", 558 | 16, 559 | 16, 560 | 192, 561 | LW_MODE_CTR, 562 | LW_CIPHER_SIMON_192_128_CTR, 563 | 0, 564 | LW_CIPHER_BASE_INDEX_SIMON 565 | }; 566 | 567 | static const lw_cipher_info_t lw_cipher_simon_256_128_ecb_info = { 568 | "SIMON-256_128-ECB", 569 | 16, 570 | 0, 571 | 256, 572 | LW_MODE_ECB, 573 | LW_CIPHER_SIMON_256_128_ECB, 574 | 0, 575 | LW_CIPHER_BASE_INDEX_SIMON 576 | }; 577 | 578 | static const lw_cipher_info_t lw_cipher_simon_256_128_cbc_info = { 579 | "SIMON-256_128-CBC", 580 | 16, 581 | 16, 582 | 256, 583 | LW_MODE_CBC, 584 | LW_CIPHER_SIMON_256_128_CBC, 585 | 0, 586 | LW_CIPHER_BASE_INDEX_SIMON 587 | }; 588 | 589 | static const lw_cipher_info_t lw_cipher_simon_256_128_ctr_info = { 590 | "SIMON-256_128-CTR", 591 | 16, 592 | 16, 593 | 256, 594 | LW_MODE_CTR, 595 | LW_CIPHER_SIMON_256_128_CTR, 596 | 0, 597 | LW_CIPHER_BASE_INDEX_SIMON 598 | }; 599 | 600 | static int speck_crypt_ecb_wrap(void *ctx, lw_operation_t operation, 601 | const uint8_t *input, uint8_t *output) 602 | { 603 | return lw_speck_crypt_ecb((lw_speck_context *) ctx, operation, input, 604 | output); 605 | } 606 | 607 | static int speck_crypt_cbc_wrap(void *ctx, lw_operation_t operation, 608 | size_t length, uint8_t *iv, 609 | const uint8_t *input, uint8_t *output) 610 | { 611 | return lw_speck_crypt_cbc((lw_speck_context *) ctx, operation, length, iv, 612 | input, output); 613 | } 614 | 615 | static int speck_crypt_ctr_wrap(void *ctx, size_t length, uint8_t *nc_off, 616 | uint8_t *nonce_counter, 617 | uint8_t *stream_block, const uint8_t *input, 618 | uint8_t *output) 619 | { 620 | return lw_speck_crypt_ctr((lw_speck_context *) ctx, length, nc_off, 621 | nonce_counter, stream_block, input, output); 622 | } 623 | 624 | static int speck_setkey_enc_wrap(void *ctx, const uint8_t *key, 625 | unsigned int key_bitlen) 626 | { 627 | return lw_speck_setkey((lw_speck_context *) ctx, key, key_bitlen); 628 | } 629 | 630 | static int speck_setkey_dec_wrap(void *ctx, const uint8_t *key, 631 | unsigned int key_bitlen) 632 | { 633 | return lw_speck_setkey((lw_speck_context *) ctx, key, key_bitlen); 634 | } 635 | 636 | static void *speck_ctx_alloc(uint8_t block_size) 637 | { 638 | lw_speck_context *ctx = (lw_speck_context *) malloc( 639 | sizeof(lw_speck_context)); 640 | if (ctx == NULL) { 641 | return NULL; 642 | } 643 | lw_speck_init(ctx, block_size); 644 | return ctx; 645 | } 646 | 647 | static void speck_ctx_free(void *ctx) 648 | { 649 | lw_speck_free((lw_speck_context *) ctx); 650 | free(ctx); 651 | } 652 | 653 | static const lw_cipher_base_t speck_info = { 654 | LW_CIPHER_ID_SPECK, 655 | speck_crypt_ecb_wrap, 656 | speck_crypt_cbc_wrap, 657 | speck_crypt_ctr_wrap, 658 | speck_setkey_enc_wrap, 659 | speck_setkey_dec_wrap, 660 | speck_ctx_alloc, 661 | speck_ctx_free 662 | }; 663 | 664 | static const lw_cipher_info_t lw_cipher_speck_64_32_ecb_info = { 665 | "SPECK-64_32-ECB", 666 | 4, 667 | 0, 668 | 64, 669 | LW_MODE_ECB, 670 | LW_CIPHER_SPECK_64_32_ECB, 671 | 0, 672 | LW_CIPHER_BASE_INDEX_SPECK 673 | }; 674 | 675 | static const lw_cipher_info_t lw_cipher_speck_64_32_cbc_info = { 676 | "SPECK-64_32-CBC", 677 | 4, 678 | 4, 679 | 64, 680 | LW_MODE_CBC, 681 | LW_CIPHER_SPECK_64_32_CBC, 682 | 0, 683 | LW_CIPHER_BASE_INDEX_SPECK 684 | }; 685 | 686 | static const lw_cipher_info_t lw_cipher_speck_64_32_ctr_info = { 687 | "SPECK-64_32-CTR", 688 | 4, 689 | 4, 690 | 64, 691 | LW_MODE_CTR, 692 | LW_CIPHER_SPECK_64_32_CTR, 693 | 0, 694 | LW_CIPHER_BASE_INDEX_SPECK 695 | }; 696 | 697 | static const lw_cipher_info_t lw_cipher_speck_72_48_ecb_info = { 698 | "SPECK-72_48-ECB", 699 | 6, 700 | 0, 701 | 72, 702 | LW_MODE_ECB, 703 | LW_CIPHER_SPECK_72_48_ECB, 704 | 0, 705 | LW_CIPHER_BASE_INDEX_SPECK 706 | }; 707 | 708 | static const lw_cipher_info_t lw_cipher_speck_72_48_cbc_info = { 709 | "SPECK-72_48-CBC", 710 | 6, 711 | 6, 712 | 72, 713 | LW_MODE_CBC, 714 | LW_CIPHER_SPECK_72_48_CBC, 715 | 0, 716 | LW_CIPHER_BASE_INDEX_SPECK 717 | }; 718 | 719 | static const lw_cipher_info_t lw_cipher_speck_72_48_ctr_info = { 720 | "SPECK-72_48-CTR", 721 | 6, 722 | 6, 723 | 72, 724 | LW_MODE_CTR, 725 | LW_CIPHER_SPECK_72_48_CTR, 726 | 0, 727 | LW_CIPHER_BASE_INDEX_SPECK 728 | }; 729 | 730 | static const lw_cipher_info_t lw_cipher_speck_96_48_ecb_info = { 731 | "SPECK-96_48-ECB", 732 | 6, 733 | 0, 734 | 96, 735 | LW_MODE_ECB, 736 | LW_CIPHER_SPECK_96_48_ECB, 737 | 0, 738 | LW_CIPHER_BASE_INDEX_SPECK 739 | }; 740 | 741 | static const lw_cipher_info_t lw_cipher_speck_96_48_cbc_info = { 742 | "SPECK-96_48-CBC", 743 | 6, 744 | 6, 745 | 96, 746 | LW_MODE_CBC, 747 | LW_CIPHER_SPECK_96_48_CBC, 748 | 0, 749 | LW_CIPHER_BASE_INDEX_SPECK 750 | }; 751 | 752 | static const lw_cipher_info_t lw_cipher_speck_96_48_ctr_info = { 753 | "SPECK-96_48-CTR", 754 | 6, 755 | 6, 756 | 96, 757 | LW_MODE_CTR, 758 | LW_CIPHER_SPECK_96_48_CTR, 759 | 0, 760 | LW_CIPHER_BASE_INDEX_SPECK 761 | }; 762 | 763 | static const lw_cipher_info_t lw_cipher_speck_96_64_ecb_info = { 764 | "SPECK-96_64-ECB", 765 | 8, 766 | 0, 767 | 96, 768 | LW_MODE_ECB, 769 | LW_CIPHER_SPECK_96_64_ECB, 770 | 0, 771 | LW_CIPHER_BASE_INDEX_SPECK 772 | }; 773 | 774 | static const lw_cipher_info_t lw_cipher_speck_96_64_cbc_info = { 775 | "SPECK-96_64-CBC", 776 | 8, 777 | 8, 778 | 96, 779 | LW_MODE_CBC, 780 | LW_CIPHER_SPECK_96_64_CBC, 781 | 0, 782 | LW_CIPHER_BASE_INDEX_SPECK 783 | }; 784 | 785 | static const lw_cipher_info_t lw_cipher_speck_96_64_ctr_info = { 786 | "SPECK-96_64-CTR", 787 | 8, 788 | 8, 789 | 96, 790 | LW_MODE_CTR, 791 | LW_CIPHER_SPECK_96_64_CTR, 792 | 0, 793 | LW_CIPHER_BASE_INDEX_SPECK 794 | }; 795 | 796 | static const lw_cipher_info_t lw_cipher_speck_128_64_ecb_info = { 797 | "SPECK-128_64-ECB", 798 | 8, 799 | 0, 800 | 128, 801 | LW_MODE_ECB, 802 | LW_CIPHER_SPECK_128_64_ECB, 803 | 0, 804 | LW_CIPHER_BASE_INDEX_SPECK 805 | }; 806 | 807 | static const lw_cipher_info_t lw_cipher_speck_128_64_cbc_info = { 808 | "SPECK-128_64-CBC", 809 | 8, 810 | 8, 811 | 128, 812 | LW_MODE_CBC, 813 | LW_CIPHER_SPECK_128_64_CBC, 814 | 0, 815 | LW_CIPHER_BASE_INDEX_SPECK 816 | }; 817 | 818 | static const lw_cipher_info_t lw_cipher_speck_128_64_ctr_info = { 819 | "SPECK-128_64-CTR", 820 | 8, 821 | 8, 822 | 128, 823 | LW_MODE_CTR, 824 | LW_CIPHER_SPECK_128_64_CTR, 825 | 0, 826 | LW_CIPHER_BASE_INDEX_SPECK 827 | }; 828 | 829 | static const lw_cipher_info_t lw_cipher_speck_96_96_ecb_info = { 830 | "SPECK-96_96-ECB", 831 | 12, 832 | 0, 833 | 96, 834 | LW_MODE_ECB, 835 | LW_CIPHER_SPECK_96_96_ECB, 836 | 0, 837 | LW_CIPHER_BASE_INDEX_SPECK 838 | }; 839 | 840 | static const lw_cipher_info_t lw_cipher_speck_96_96_cbc_info = { 841 | "SPECK-96_96-CBC", 842 | 12, 843 | 12, 844 | 96, 845 | LW_MODE_CBC, 846 | LW_CIPHER_SPECK_96_96_CBC, 847 | 0, 848 | LW_CIPHER_BASE_INDEX_SPECK 849 | }; 850 | 851 | static const lw_cipher_info_t lw_cipher_speck_96_96_ctr_info = { 852 | "SPECK-96_96-CTR", 853 | 12, 854 | 12, 855 | 96, 856 | LW_MODE_CTR, 857 | LW_CIPHER_SPECK_96_96_CTR, 858 | 0, 859 | LW_CIPHER_BASE_INDEX_SPECK 860 | }; 861 | 862 | static const lw_cipher_info_t lw_cipher_speck_144_96_ecb_info = { 863 | "SPECK-144_96-ECB", 864 | 12, 865 | 0, 866 | 144, 867 | LW_MODE_ECB, 868 | LW_CIPHER_SPECK_144_96_ECB, 869 | 0, 870 | LW_CIPHER_BASE_INDEX_SPECK 871 | }; 872 | 873 | static const lw_cipher_info_t lw_cipher_speck_144_96_cbc_info = { 874 | "SPECK-144_96-CBC", 875 | 12, 876 | 12, 877 | 144, 878 | LW_MODE_CBC, 879 | LW_CIPHER_SPECK_144_96_CBC, 880 | 0, 881 | LW_CIPHER_BASE_INDEX_SPECK 882 | }; 883 | 884 | static const lw_cipher_info_t lw_cipher_speck_144_96_ctr_info = { 885 | "SPECK-144_96-CTR", 886 | 12, 887 | 12, 888 | 144, 889 | LW_MODE_CTR, 890 | LW_CIPHER_SPECK_144_96_CTR, 891 | 0, 892 | LW_CIPHER_BASE_INDEX_SPECK 893 | }; 894 | 895 | static const lw_cipher_info_t lw_cipher_speck_128_128_ecb_info = { 896 | "SPECK-128_128-ECB", 897 | 16, 898 | 0, 899 | 128, 900 | LW_MODE_ECB, 901 | LW_CIPHER_SPECK_128_128_ECB, 902 | 0, 903 | LW_CIPHER_BASE_INDEX_SPECK 904 | }; 905 | 906 | static const lw_cipher_info_t lw_cipher_speck_128_128_cbc_info = { 907 | "SPECK-128_128-CBC", 908 | 16, 909 | 16, 910 | 128, 911 | LW_MODE_CBC, 912 | LW_CIPHER_SPECK_128_128_CBC, 913 | 0, 914 | LW_CIPHER_BASE_INDEX_SPECK 915 | }; 916 | 917 | static const lw_cipher_info_t lw_cipher_speck_128_128_ctr_info = { 918 | "SPECK-128_128-CTR", 919 | 16, 920 | 16, 921 | 128, 922 | LW_MODE_CTR, 923 | LW_CIPHER_SPECK_128_128_CTR, 924 | 0, 925 | LW_CIPHER_BASE_INDEX_SPECK 926 | }; 927 | 928 | static const lw_cipher_info_t lw_cipher_speck_192_128_ecb_info = { 929 | "SPECK-192_128-ECB", 930 | 16, 931 | 0, 932 | 192, 933 | LW_MODE_ECB, 934 | LW_CIPHER_SPECK_192_128_ECB, 935 | 0, 936 | LW_CIPHER_BASE_INDEX_SPECK 937 | }; 938 | 939 | static const lw_cipher_info_t lw_cipher_speck_192_128_cbc_info = { 940 | "SPECK-192_128-CBC", 941 | 16, 942 | 16, 943 | 192, 944 | LW_MODE_CBC, 945 | LW_CIPHER_SPECK_192_128_CBC, 946 | 0, 947 | LW_CIPHER_BASE_INDEX_SPECK 948 | }; 949 | 950 | static const lw_cipher_info_t lw_cipher_speck_192_128_ctr_info = { 951 | "SPECK-192_128-CTR", 952 | 16, 953 | 16, 954 | 192, 955 | LW_MODE_CTR, 956 | LW_CIPHER_SPECK_192_128_CTR, 957 | 0, 958 | LW_CIPHER_BASE_INDEX_SPECK 959 | }; 960 | 961 | static const lw_cipher_info_t lw_cipher_speck_256_128_ecb_info = { 962 | "SPECK-256_128-ECB", 963 | 16, 964 | 0, 965 | 256, 966 | LW_MODE_ECB, 967 | LW_CIPHER_SPECK_256_128_ECB, 968 | 0, 969 | LW_CIPHER_BASE_INDEX_SPECK 970 | }; 971 | 972 | static const lw_cipher_info_t lw_cipher_speck_256_128_cbc_info = { 973 | "SPECK-256_128-CBC", 974 | 16, 975 | 16, 976 | 256, 977 | LW_MODE_CBC, 978 | LW_CIPHER_SPECK_256_128_CBC, 979 | 0, 980 | LW_CIPHER_BASE_INDEX_SPECK 981 | }; 982 | 983 | static const lw_cipher_info_t lw_cipher_speck_256_128_ctr_info = { 984 | "SPECK-256_128-CTR", 985 | 16, 986 | 16, 987 | 256, 988 | LW_MODE_CTR, 989 | LW_CIPHER_SPECK_256_128_CTR, 990 | 0, 991 | LW_CIPHER_BASE_INDEX_SPECK 992 | }; 993 | 994 | static int present_crypt_ecb_wrap(void *ctx, lw_operation_t operation, 995 | const uint8_t *input, uint8_t *output) 996 | { 997 | return lw_present_crypt_ecb((lw_present_context *) ctx, operation, input, 998 | output); 999 | } 1000 | 1001 | static int present_crypt_cbc_wrap(void *ctx, lw_operation_t operation, 1002 | size_t length, uint8_t *iv, 1003 | const uint8_t *input, uint8_t *output) 1004 | { 1005 | return lw_present_crypt_cbc((lw_present_context *) ctx, operation, length, 1006 | iv, input, output); 1007 | } 1008 | 1009 | static int present_crypt_ctr_wrap(void *ctx, size_t length, uint8_t *nc_off, 1010 | uint8_t *nonce_counter, 1011 | uint8_t *stream_block, const uint8_t *input, 1012 | uint8_t *output) 1013 | { 1014 | return lw_present_crypt_ctr((lw_present_context *) ctx, length, nc_off, 1015 | nonce_counter, stream_block, input, output); 1016 | } 1017 | 1018 | static int present_setkey_enc_wrap(void *ctx, const uint8_t *key, 1019 | unsigned int key_bitlen) 1020 | { 1021 | return lw_present_setkey((lw_present_context *) ctx, key, key_bitlen); 1022 | } 1023 | 1024 | static int present_setkey_dec_wrap(void *ctx, const uint8_t *key, 1025 | unsigned int key_bitlen) 1026 | { 1027 | return lw_present_setkey((lw_present_context *) ctx, key, key_bitlen); 1028 | } 1029 | 1030 | static void *present_ctx_alloc(uint8_t block_size) 1031 | { 1032 | lw_present_context *ctx = (lw_present_context *) malloc( 1033 | sizeof(lw_present_context)); 1034 | if (ctx == NULL) { 1035 | return NULL; 1036 | } 1037 | lw_present_init(ctx); 1038 | return ctx; 1039 | } 1040 | 1041 | static void present_ctx_free(void *ctx) 1042 | { 1043 | lw_present_free((lw_present_context *) ctx); 1044 | free(ctx); 1045 | } 1046 | 1047 | static const lw_cipher_base_t present_info = { 1048 | LW_CIPHER_ID_PRESENT, 1049 | present_crypt_ecb_wrap, 1050 | present_crypt_cbc_wrap, 1051 | present_crypt_ctr_wrap, 1052 | present_setkey_enc_wrap, 1053 | present_setkey_dec_wrap, 1054 | present_ctx_alloc, 1055 | present_ctx_free 1056 | }; 1057 | 1058 | static const lw_cipher_info_t lw_cipher_present_80_ecb_info = { 1059 | "PRESENT-80-ECB", 1060 | 8, 1061 | 0, 1062 | 80, 1063 | LW_MODE_ECB, 1064 | LW_CIPHER_PRESENT_80_ECB, 1065 | 0, 1066 | LW_CIPHER_BASE_INDEX_PRESENT 1067 | }; 1068 | 1069 | static const lw_cipher_info_t lw_cipher_present_80_cbc_info = { 1070 | "PRESENT-80-CBC", 1071 | 8, 1072 | 8, 1073 | 80, 1074 | LW_MODE_CBC, 1075 | LW_CIPHER_PRESENT_80_CBC, 1076 | 0, 1077 | LW_CIPHER_BASE_INDEX_PRESENT 1078 | }; 1079 | 1080 | static const lw_cipher_info_t lw_cipher_present_80_ctr_info = { 1081 | "PRESENT-80-CTR", 1082 | 8, 1083 | 8, 1084 | 80, 1085 | LW_MODE_CTR, 1086 | LW_CIPHER_PRESENT_80_CTR, 1087 | 0, 1088 | LW_CIPHER_BASE_INDEX_PRESENT 1089 | }; 1090 | 1091 | static const lw_cipher_info_t lw_cipher_present_128_ecb_info = { 1092 | "PRESENT-128-ECB", 1093 | 8, 1094 | 0, 1095 | 128, 1096 | LW_MODE_ECB, 1097 | LW_CIPHER_PRESENT_128_ECB, 1098 | 0, 1099 | LW_CIPHER_BASE_INDEX_PRESENT 1100 | }; 1101 | 1102 | static const lw_cipher_info_t lw_cipher_present_128_cbc_info = { 1103 | "PRESENT-128-CBC", 1104 | 8, 1105 | 8, 1106 | 128, 1107 | LW_MODE_CBC, 1108 | LW_CIPHER_PRESENT_128_CBC, 1109 | 0, 1110 | LW_CIPHER_BASE_INDEX_PRESENT 1111 | }; 1112 | 1113 | static const lw_cipher_info_t lw_cipher_present_128_ctr_info = { 1114 | "PRESENT-128-CTR", 1115 | 8, 1116 | 8, 1117 | 128, 1118 | LW_MODE_CTR, 1119 | LW_CIPHER_PRESENT_128_CTR, 1120 | 0, 1121 | LW_CIPHER_BASE_INDEX_PRESENT 1122 | }; 1123 | 1124 | const lw_cipher_definition_t lw_cipher_definitions[] = { 1125 | {LW_CIPHER_XTEA_ECB,&lw_cipher_xtea_ecb_info}, 1126 | {LW_CIPHER_XTEA_CBC,&lw_cipher_xtea_cbc_info}, 1127 | {LW_CIPHER_XTEA_CTR,&lw_cipher_xtea_ctr_info}, 1128 | {LW_CIPHER_XXTEA_ECB,&lw_cipher_xxtea_ecb_info}, 1129 | {LW_CIPHER_XXTEA_CBC,&lw_cipher_xxtea_cbc_info}, 1130 | {LW_CIPHER_XXTEA_CTR,&lw_cipher_xxtea_ctr_info}, 1131 | {LW_CIPHER_SIMON_64_32_ECB,&lw_cipher_simon_64_32_ecb_info}, 1132 | {LW_CIPHER_SIMON_64_32_CBC,&lw_cipher_simon_64_32_cbc_info}, 1133 | {LW_CIPHER_SIMON_64_32_CTR,&lw_cipher_simon_64_32_ctr_info}, 1134 | {LW_CIPHER_SIMON_72_48_ECB,&lw_cipher_simon_72_48_ecb_info}, 1135 | {LW_CIPHER_SIMON_72_48_CBC,&lw_cipher_simon_72_48_cbc_info}, 1136 | {LW_CIPHER_SIMON_72_48_CTR,&lw_cipher_simon_72_48_ctr_info}, 1137 | {LW_CIPHER_SIMON_96_48_ECB,&lw_cipher_simon_96_48_ecb_info}, 1138 | {LW_CIPHER_SIMON_96_48_CBC,&lw_cipher_simon_96_48_cbc_info}, 1139 | {LW_CIPHER_SIMON_96_48_CTR,&lw_cipher_simon_96_48_ctr_info}, 1140 | {LW_CIPHER_SIMON_96_64_ECB,&lw_cipher_simon_96_64_ecb_info}, 1141 | {LW_CIPHER_SIMON_96_64_CBC,&lw_cipher_simon_96_64_cbc_info}, 1142 | {LW_CIPHER_SIMON_96_64_CTR,&lw_cipher_simon_96_64_ctr_info}, 1143 | {LW_CIPHER_SIMON_128_64_ECB,&lw_cipher_simon_128_64_ecb_info}, 1144 | {LW_CIPHER_SIMON_128_64_CBC,&lw_cipher_simon_128_64_cbc_info}, 1145 | {LW_CIPHER_SIMON_128_64_CTR,&lw_cipher_simon_128_64_ctr_info}, 1146 | {LW_CIPHER_SIMON_96_96_ECB,&lw_cipher_simon_96_96_ecb_info}, 1147 | {LW_CIPHER_SIMON_96_96_CBC,&lw_cipher_simon_96_96_cbc_info}, 1148 | {LW_CIPHER_SIMON_96_96_CTR,&lw_cipher_simon_96_96_ctr_info}, 1149 | {LW_CIPHER_SIMON_144_96_ECB,&lw_cipher_simon_144_96_ecb_info}, 1150 | {LW_CIPHER_SIMON_144_96_CBC,&lw_cipher_simon_144_96_cbc_info}, 1151 | {LW_CIPHER_SIMON_144_96_CTR,&lw_cipher_simon_144_96_ctr_info}, 1152 | {LW_CIPHER_SIMON_128_128_ECB,&lw_cipher_simon_128_128_ecb_info}, 1153 | {LW_CIPHER_SIMON_128_128_CBC,&lw_cipher_simon_128_128_cbc_info}, 1154 | {LW_CIPHER_SIMON_128_128_CTR,&lw_cipher_simon_128_128_ctr_info}, 1155 | {LW_CIPHER_SIMON_192_128_ECB,&lw_cipher_simon_192_128_ecb_info}, 1156 | {LW_CIPHER_SIMON_192_128_CBC,&lw_cipher_simon_192_128_cbc_info}, 1157 | {LW_CIPHER_SIMON_192_128_CTR,&lw_cipher_simon_192_128_ctr_info}, 1158 | {LW_CIPHER_SIMON_256_128_ECB,&lw_cipher_simon_256_128_ecb_info}, 1159 | {LW_CIPHER_SIMON_256_128_CBC,&lw_cipher_simon_256_128_cbc_info}, 1160 | {LW_CIPHER_SIMON_256_128_CTR,&lw_cipher_simon_256_128_ctr_info}, 1161 | {LW_CIPHER_SPECK_64_32_ECB,&lw_cipher_speck_64_32_ecb_info}, 1162 | {LW_CIPHER_SPECK_64_32_CBC,&lw_cipher_speck_64_32_cbc_info}, 1163 | {LW_CIPHER_SPECK_64_32_CTR,&lw_cipher_speck_64_32_ctr_info}, 1164 | {LW_CIPHER_SPECK_72_48_ECB,&lw_cipher_speck_72_48_ecb_info}, 1165 | {LW_CIPHER_SPECK_72_48_CBC,&lw_cipher_speck_72_48_cbc_info}, 1166 | {LW_CIPHER_SPECK_72_48_CTR,&lw_cipher_speck_72_48_ctr_info}, 1167 | {LW_CIPHER_SPECK_96_48_ECB,&lw_cipher_speck_96_48_ecb_info}, 1168 | {LW_CIPHER_SPECK_96_48_CBC,&lw_cipher_speck_96_48_cbc_info}, 1169 | {LW_CIPHER_SPECK_96_48_CTR,&lw_cipher_speck_96_48_ctr_info}, 1170 | {LW_CIPHER_SPECK_96_64_ECB,&lw_cipher_speck_96_64_ecb_info}, 1171 | {LW_CIPHER_SPECK_96_64_CBC,&lw_cipher_speck_96_64_cbc_info}, 1172 | {LW_CIPHER_SPECK_96_64_CTR,&lw_cipher_speck_96_64_ctr_info}, 1173 | {LW_CIPHER_SPECK_128_64_ECB,&lw_cipher_speck_128_64_ecb_info}, 1174 | {LW_CIPHER_SPECK_128_64_CBC,&lw_cipher_speck_128_64_cbc_info}, 1175 | {LW_CIPHER_SPECK_128_64_CTR,&lw_cipher_speck_128_64_ctr_info}, 1176 | {LW_CIPHER_SPECK_96_96_ECB,&lw_cipher_speck_96_96_ecb_info}, 1177 | {LW_CIPHER_SPECK_96_96_CBC,&lw_cipher_speck_96_96_cbc_info}, 1178 | {LW_CIPHER_SPECK_96_96_CTR,&lw_cipher_speck_96_96_ctr_info}, 1179 | {LW_CIPHER_SPECK_144_96_ECB,&lw_cipher_speck_144_96_ecb_info}, 1180 | {LW_CIPHER_SPECK_144_96_CBC,&lw_cipher_speck_144_96_cbc_info}, 1181 | {LW_CIPHER_SPECK_144_96_CTR,&lw_cipher_speck_144_96_ctr_info}, 1182 | {LW_CIPHER_SPECK_128_128_ECB,&lw_cipher_speck_128_128_ecb_info}, 1183 | {LW_CIPHER_SPECK_128_128_CBC,&lw_cipher_speck_128_128_cbc_info}, 1184 | {LW_CIPHER_SPECK_128_128_CTR,&lw_cipher_speck_128_128_ctr_info}, 1185 | {LW_CIPHER_SPECK_192_128_ECB,&lw_cipher_speck_192_128_ecb_info}, 1186 | {LW_CIPHER_SPECK_192_128_CBC,&lw_cipher_speck_192_128_cbc_info}, 1187 | {LW_CIPHER_SPECK_192_128_CTR,&lw_cipher_speck_192_128_ctr_info}, 1188 | {LW_CIPHER_SPECK_256_128_ECB,&lw_cipher_speck_256_128_ecb_info}, 1189 | {LW_CIPHER_SPECK_256_128_CBC,&lw_cipher_speck_256_128_cbc_info}, 1190 | {LW_CIPHER_SPECK_256_128_CTR,&lw_cipher_speck_256_128_ctr_info}, 1191 | {LW_CIPHER_PRESENT_80_ECB,&lw_cipher_present_80_ecb_info}, 1192 | {LW_CIPHER_PRESENT_80_CBC,&lw_cipher_present_80_cbc_info}, 1193 | {LW_CIPHER_PRESENT_80_CTR,&lw_cipher_present_80_ctr_info}, 1194 | {LW_CIPHER_PRESENT_128_ECB,&lw_cipher_present_128_ecb_info}, 1195 | {LW_CIPHER_PRESENT_128_CBC,&lw_cipher_present_128_cbc_info}, 1196 | {LW_CIPHER_PRESENT_128_CTR,&lw_cipher_present_128_ctr_info} 1197 | }; 1198 | 1199 | //const lw_cipher_base_t *lw_cipher_base_lookup_table[] = { 1200 | // [LW_CIPHER_BASE_INDEX_XTEA] = &xtea_info, 1201 | // [LW_CIPHER_BASE_INDEX_XXTEA] = &xxtea_info, 1202 | // [LW_CIPHER_BASE_INDEX_SIMON] = &simon_info, 1203 | // [LW_CIPHER_BASE_INDEX_SPECK] = &speck_info, 1204 | // [LW_CIPHER_BASE_INDEX_PRESENT] = &present_info 1205 | //}; 1206 | 1207 | const lw_cipher_base_t *lw_cipher_base_lookup_table[] = { 1208 | &xtea_info, 1209 | &xxtea_info, 1210 | &simon_info, 1211 | &speck_info, 1212 | &present_info 1213 | }; -------------------------------------------------------------------------------- /src/present.c: -------------------------------------------------------------------------------- 1 | #include "present.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #define ROUNDS 32 7 | #define ROUND_KEY_SIZE_BYTES 8 8 | #define PRESENT_BLOCK_SIZE_BYTES 8 9 | // In reality, if you want to use 128 bit present, you should probably just use aes... 10 | 11 | unsigned char sBox[16] = { 12 | 0xC, 0x5, 0x6, 0xB, 0x9, 0x0, 0xA, 0xD, 0x3, 0xE, 0xF, 0x8, 0x4, 0x7, 0x1, 0x2}; 13 | 14 | unsigned char sBoxInverse[16] = { 15 | 0x5, 0xE, 0xF, 0x8, 0xC, 0x1, 0x2, 0xD, 0xB, 0x4, 0x6, 0x3, 0x0, 0x7, 0x9, 0xA}; 16 | 17 | void lw_present_init(lw_present_context *ctx) 18 | { 19 | memset(ctx, 0, sizeof(lw_present_context)); 20 | } 21 | 22 | void lw_present_free(lw_present_context *ctx) 23 | { 24 | memset(ctx, 0, sizeof(lw_present_context)); 25 | } 26 | 27 | int lw_present_setkey(lw_present_context *ctx, const uint8_t *key, uint16_t key_bitlen) 28 | { 29 | if (key_bitlen != 80 && key_bitlen != 128) { 30 | return LW_ERR_PRESENT_INVALID_CONFIG; 31 | } 32 | ctx->key_bitlen = key_bitlen; 33 | memcpy(ctx->key, key, key_bitlen / 8); 34 | if (key_bitlen == 80) { 35 | // trashable key copies 36 | unsigned char key1[10]; 37 | unsigned char key2[10]; 38 | unsigned char i, j; 39 | memcpy(key1, key, 10); 40 | memcpy(ctx->round_key, key1, 8); 41 | for (i = 1; i < ROUNDS; i++) { 42 | // rotate left 61 bits 43 | for (j = 0; j < 10; j++) { 44 | key2[j] = (key1[(j + 7) % 10] << 5) | 45 | (key1[(j + 8) % 10] >> 3); 46 | } 47 | memcpy(key1, key2, 10); 48 | 49 | // pass leftmost 4-bits through sBox 50 | key1[0] = (sBox[key1[0] >> 4] << 4) | (key1[0] & 0xF); 51 | 52 | // xor roundCounter into bits 15 through 19 53 | key1[8] ^= i << 7; // bit 15 54 | key1[7] ^= i >> 1; // bits 19-16 55 | memcpy(ctx->round_key[i], key1, 8); 56 | } 57 | } else { 58 | unsigned char key1[16]; 59 | unsigned char key2[16]; 60 | unsigned char i, j; 61 | memcpy(key1, key, 16); 62 | memcpy(ctx->round_key, key1, 8); 63 | for (i = 1; i < ROUNDS; i++) { 64 | // rotate left 61 bits 65 | for (j = 0; j < 16; j++) { 66 | key2[j] = (key1[(j + 7) % 16] << 5) | (key1[(j + 8) % 16] >> 3); 67 | } 68 | memcpy(key1, key2, 16); 69 | 70 | // pass leftmost 8-bits through sBoxes 71 | key1[0] = (sBox[key1[0] >> 4] << 4) | (sBox[key1[0] & 0xF]); 72 | 73 | // xor roundCounter into bits 62 through 66 74 | key1[8] ^= i << 6; // bits 63-62 75 | key1[7] ^= i >> 2; // bits 66-64 76 | 77 | memcpy(ctx->round_key[i], key1, 8); 78 | } 79 | } 80 | return 0; 81 | } 82 | 83 | int lw_present_crypt_ecb(lw_present_context *ctx, const uint8_t mode, const uint8_t *input, uint8_t *output) 84 | { 85 | if (ctx->key_bitlen != 80 && ctx->key_bitlen != 128) { 86 | return LW_ERR_PRESENT_INVALID_CONFIG; 87 | } 88 | if (mode != PRESENT_ENCRYPT && mode != PRESENT_DECRYPT) { 89 | return LW_ERR_PRESENT_BAD_INPUT_DATA; 90 | } 91 | if (ctx->key_bitlen == 80 && mode == PRESENT_ENCRYPT) { 92 | unsigned char i, j; 93 | memcpy(output, input, 8); 94 | for (i = 0; i < ROUNDS - 1; i++) { 95 | for (int k = 0; k < 8; k++) 96 | output[k] ^= ctx->round_key[i][k]; 97 | for (j = 0; j < 8; j++) { 98 | output[j] = (sBox[output[j] >> 4] << 4) | sBox[output[j] & 0xF]; 99 | } 100 | // pLayer(output); 101 | { 102 | unsigned char m, n, indexVal, andVal; 103 | unsigned char initial[8]; 104 | memcpy(initial, output, 8); 105 | for (m = 0; m < 8; m++) { 106 | output[m] = 0; 107 | for (n = 0; n < 8; n++) { 108 | indexVal = 4 * (m % 2) + (3 - (n >> 1)); 109 | andVal = (8 >> (m >> 1)) << ((n % 2) << 2); 110 | output[m] |= ((initial[indexVal] & andVal) != 0) << n; 111 | } 112 | } 113 | } 114 | } 115 | for (int k = 0; k < 8; k++) 116 | output[k] ^= ctx->round_key[ROUNDS - 1][k]; 117 | } else if (ctx->key_bitlen == 80 && mode == PRESENT_DECRYPT) { 118 | unsigned char i, j; 119 | memcpy(output, input, 8); 120 | for (i = ROUNDS - 1; i > 0; i--) { 121 | for (int k = 0; k < 8; k++) 122 | output[k] ^= ctx->round_key[i][k]; 123 | // pLayerInverse(block); 124 | { 125 | unsigned char m, n, indexVal, andVal; 126 | unsigned char initial[PRESENT_BLOCK_SIZE_BYTES]; 127 | memcpy(initial, output, PRESENT_BLOCK_SIZE_BYTES); 128 | for (m = 0; m < PRESENT_BLOCK_SIZE_BYTES; m++) { 129 | output[m] = 0; 130 | for (n = 0; n < 8; n++) { 131 | indexVal = (7 - ((2 * n) % 8)) - (m < 4); 132 | andVal = (7 - ((2 * m) % 8)) - (n < 4); 133 | output[m] |= ((initial[indexVal] & (1 << andVal)) != 0) << n; 134 | } 135 | } 136 | } 137 | for (j = 0; j < PRESENT_BLOCK_SIZE_BYTES; j++) { 138 | output[j] = (sBoxInverse[output[j] >> 4] << 4) | sBoxInverse[output[j] & 0xF]; 139 | } 140 | } 141 | for (int k = 0; k < 8; k++) 142 | output[k] ^= ctx->round_key[0][k]; 143 | } else if (ctx->key_bitlen == 128 && mode == PRESENT_ENCRYPT) { 144 | unsigned char i, j; 145 | memcpy(output, input, 8); 146 | for (i = 0; i < ROUNDS - 1; i++) { 147 | for (int k = 0; k < 8; k++) 148 | output[k] ^= ctx->round_key[i][k]; 149 | for (j = 0; j < 8; j++) { 150 | output[j] = (sBox[output[j] >> 4] << 4) | sBox[output[j] & 0xF]; 151 | } 152 | //pLayer(block) 153 | { 154 | unsigned char m, n, indexVal, andVal; 155 | unsigned char initial[8]; 156 | memcpy(initial, output, 8); 157 | for (m = 0; m < 8; m++) { 158 | output[m] = 0; 159 | for (n = 0; n < 8; n++) { 160 | indexVal = 4 * (m % 2) + (3 - (n >> 1)); 161 | andVal = (8 >> (m >> 1)) << ((n % 2) << 2); 162 | output[m] |= ((initial[indexVal] & andVal) != 0) << n; 163 | } 164 | } 165 | } 166 | } 167 | for (int k = 0; k < 8; k++) 168 | output[k] ^= ctx->round_key[ROUNDS - 1][k]; 169 | } else if (ctx->key_bitlen == 128 && mode == PRESENT_DECRYPT) { 170 | unsigned char i, j; 171 | memcpy(output, input, 8); 172 | for (i = ROUNDS - 1; i > 0; i--) { 173 | for (int k = 0; k < 8; k++) 174 | output[k] ^= ctx->round_key[i][k]; 175 | //pLayerInverse(block) 176 | { 177 | unsigned char m, n, indexVal, andVal; 178 | unsigned char initial[8]; 179 | memcpy(initial, output, 8); 180 | for (m = 0; m < 8; m++) { 181 | output[m] = 0; 182 | for (n = 0; n < 8; n++) { 183 | indexVal = (7 - ((2 * n) % 8)) - (m < 4); 184 | andVal = (7 - ((2 * m) % 8)) - (n < 4); 185 | output[m] |= ((initial[indexVal] & (1 << andVal)) != 0) << n; 186 | } 187 | } 188 | } 189 | for (j = 0; j < 8; j++) { 190 | output[j] = (sBoxInverse[output[j] >> 4] << 4) | sBoxInverse[output[j] & 0xF]; 191 | } 192 | } 193 | for (int k = 0; k < 8; k++) 194 | output[k] ^= ctx->round_key[0][k]; 195 | } 196 | return 0; 197 | } 198 | 199 | int 200 | lw_present_crypt_cbc(lw_present_context *ctx, const uint8_t mode, size_t length, uint8_t *iv, const uint8_t *input, 201 | uint8_t *output) 202 | { 203 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 204 | if (ctx->key_bitlen != 80 && ctx->key_bitlen != 128) { 205 | return LW_ERR_PRESENT_INVALID_CONFIG; 206 | } 207 | if (mode != PRESENT_ENCRYPT && mode != PRESENT_DECRYPT) { 208 | return LW_ERR_PRESENT_BAD_INPUT_DATA; 209 | } 210 | if (length == 0) { 211 | return 0; 212 | } 213 | if (length % 8) { 214 | return LW_ERR_PRESENT_INVALID_INPUT_LENGTH; 215 | } 216 | const unsigned char *ivp = iv; 217 | unsigned char temp[8]; 218 | if (mode == PRESENT_DECRYPT) { 219 | while (length > 0) { 220 | memcpy(temp, input, 8); 221 | ret = lw_present_crypt_ecb(ctx, mode, input, output); 222 | if (ret != 0) { 223 | return ret; 224 | } 225 | for (int i = 0; i < 8; i++) { 226 | output[i] = iv[i] ^ output[i]; 227 | } 228 | memcpy(iv, temp, 8); 229 | input += 8; 230 | output += 8; 231 | length -= 8; 232 | } 233 | } else { 234 | while (length > 0) { 235 | for (int i = 0; i < 8; i++) { 236 | output[i] = ivp[i] ^ input[i]; 237 | } 238 | ret = lw_present_crypt_ecb(ctx, mode, output, output); 239 | if (ret != 0) { 240 | return ret; 241 | } 242 | ivp = output; 243 | input += 8; 244 | output += 8; 245 | length -= 8; 246 | } 247 | } 248 | memcpy(iv, ivp, 8); 249 | return 0; 250 | } 251 | 252 | int lw_present_crypt_ctr(lw_present_context *ctx, size_t length, uint8_t *nc_off, uint8_t nonce_counter[8], 253 | uint8_t stream_block[8], const uint8_t *input, uint8_t *output) 254 | { 255 | if (ctx->key_bitlen != 80 && ctx->key_bitlen != 128) { 256 | return LW_ERR_PRESENT_INVALID_CONFIG; 257 | } 258 | if (length == 0) { 259 | return 0; 260 | } 261 | // if (length % 8) { 262 | // return LW_ERR_PRESENT_INVALID_INPUT_LENGTH; 263 | // } 264 | int c, i; 265 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 266 | size_t n; 267 | n = *nc_off; 268 | if (n > 0b0111) { 269 | return LW_ERR_PRESENT_BAD_INPUT_DATA; 270 | } 271 | while (length--) { 272 | if (n == 0) { 273 | ret = lw_present_crypt_ecb(ctx, PRESENT_ENCRYPT, nonce_counter, stream_block); 274 | if (ret != 0) { 275 | return ret; 276 | } 277 | 278 | for (i = 8; i > 0; i--) { 279 | if (++nonce_counter[i - 1] != 0) { 280 | break; 281 | } 282 | } 283 | } 284 | c = *input++; 285 | *output++ = (unsigned char) (c ^ stream_block[n]); 286 | n = (n + 1) & 0b0111; 287 | } 288 | *nc_off = n; 289 | ret = 0; 290 | return ret; 291 | } 292 | 293 | int lw_present_self_test(int verbose) 294 | { 295 | int ret; 296 | unsigned char key80[10] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23}; 297 | unsigned char key128[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 298 | 0xCD, 0xEF}; 299 | const unsigned char plaintext[32] = 300 | {0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, 301 | 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4, 302 | 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, 303 | 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE}; 304 | unsigned char cipher_buffer[32] = {0}; 305 | unsigned char dec_plain_buffer[32] = {0}; 306 | unsigned char iv[8] = {0}; 307 | unsigned char nonce_counter[8] = {0}; 308 | 309 | lw_present_context ctx; 310 | lw_present_init(&ctx); 311 | lw_present_setkey(&ctx, key80, 80); 312 | lw_present_crypt_ecb(&ctx, PRESENT_ENCRYPT, plaintext, cipher_buffer); 313 | lw_present_crypt_ecb(&ctx, PRESENT_DECRYPT, cipher_buffer, dec_plain_buffer); 314 | ret = memcmp(plaintext, dec_plain_buffer, 8); 315 | if (ret != 0) { 316 | printf("Present 80 bit key ecb self test failed!\n"); 317 | return ret; 318 | } else { 319 | printf("Present 80 bit key ecb self test passed!\n"); 320 | } 321 | 322 | lw_present_init(&ctx); 323 | lw_present_setkey(&ctx, key128, 128); 324 | lw_present_crypt_ecb(&ctx, PRESENT_ENCRYPT, plaintext, cipher_buffer); 325 | lw_present_crypt_ecb(&ctx, PRESENT_DECRYPT, cipher_buffer, dec_plain_buffer); 326 | ret = memcmp(plaintext, dec_plain_buffer, 8); 327 | if (ret != 0) { 328 | printf("Present 128 bit key ecb self test failed!\n"); 329 | return ret; 330 | } else { 331 | printf("Present 128 bit key ecb self test passed!\n"); 332 | } 333 | 334 | lw_present_init(&ctx); 335 | lw_present_setkey(&ctx, key80, 80); 336 | lw_present_crypt_cbc(&ctx, PRESENT_ENCRYPT, 32, iv, plaintext, cipher_buffer); 337 | memset(iv, 0, 8); 338 | lw_present_crypt_cbc(&ctx, PRESENT_DECRYPT, 32, iv, cipher_buffer, dec_plain_buffer); 339 | ret = memcmp(plaintext, dec_plain_buffer, 32); 340 | if (ret != 0) { 341 | printf("Present 80 bit key cbc self test failed!\n"); 342 | return ret; 343 | } else { 344 | printf("Present 80 bit key cbc self test passed!\n"); 345 | } 346 | 347 | lw_present_init(&ctx); 348 | lw_present_setkey(&ctx, key128, 128); 349 | memset(iv, 0, 8); 350 | lw_present_crypt_cbc(&ctx, PRESENT_ENCRYPT, 32, iv, plaintext, cipher_buffer); 351 | memset(iv, 0, 8); 352 | lw_present_crypt_cbc(&ctx, PRESENT_DECRYPT, 32, iv, cipher_buffer, dec_plain_buffer); 353 | ret = memcmp(plaintext, dec_plain_buffer, 32); 354 | if (ret != 0) { 355 | printf("Present 128 bit key cbc self test failed!\n"); 356 | return ret; 357 | } else { 358 | printf("Present 128 bit key cbc self test passed!\n"); 359 | } 360 | 361 | uint8_t nc = 0; 362 | unsigned char stream_block[8] = {0}; 363 | unsigned char nonce_counter_for_enc[8] = {0}; 364 | memcpy(nonce_counter_for_enc, nonce_counter, 8); 365 | lw_present_init(&ctx); 366 | lw_present_setkey(&ctx, key80, 80); 367 | lw_present_crypt_ctr(&ctx, 32, &nc, nonce_counter_for_enc, stream_block, plaintext, cipher_buffer); 368 | nc = 0; 369 | lw_present_crypt_ctr(&ctx, 32, &nc, nonce_counter, stream_block, cipher_buffer, dec_plain_buffer); 370 | ret = memcmp(plaintext, dec_plain_buffer, 32); 371 | if (ret != 0) { 372 | printf("Present 80 bit key ctr self test failed!\n"); 373 | return ret; 374 | } else { 375 | printf("Present 80 bit key ctr self test passed!\n"); 376 | } 377 | 378 | memcpy(nonce_counter_for_enc, nonce_counter, 8); 379 | lw_present_init(&ctx); 380 | lw_present_setkey(&ctx, key128, 128); 381 | lw_present_crypt_ctr(&ctx, 32, &nc, nonce_counter_for_enc, stream_block, plaintext, cipher_buffer); 382 | nc = 0; 383 | lw_present_crypt_ctr(&ctx, 32, &nc, nonce_counter, stream_block, cipher_buffer, dec_plain_buffer); 384 | ret = memcmp(plaintext, dec_plain_buffer, 32); 385 | if (ret != 0) { 386 | printf("Present 128 bit key ctr self test failed!\n"); 387 | return ret; 388 | } else { 389 | printf("Present 128 bit key ctr self test passed!\n"); 390 | } 391 | return 0; 392 | } 393 | -------------------------------------------------------------------------------- /src/simon.c: -------------------------------------------------------------------------------- 1 | #include "simon.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Cipher Operation Macros 9 | #define shift_one(x_word) (((x_word) << 1) | ((x_word) >> (word_size - 1))) 10 | #define shift_eight(x_word) (((x_word) << 8) | ((x_word) >> (word_size - 8))) 11 | #define shift_two(x_word) (((x_word) << 2) | ((x_word) >> (word_size - 2))) 12 | 13 | #define rshift_three(x) (((x) >> 3) | (((x) & 0x7) << (word_size - 3))) 14 | #define rshift_one(x) (((x) >> 1) | (((x) & 0x1) << (word_size - 1))) 15 | 16 | uint64_t z_arrays[5] = {0b0001100111000011010100100010111110110011100001101010010001011111, 17 | 0b0001011010000110010011111011100010101101000011001001111101110001, 18 | 0b0011001101101001111110001000010100011001001011000000111011110101, 19 | 0b0011110000101100111001010001001000000111101001100011010111011011, 20 | 0b0011110111001001010011000011101000000100011011010110011110001011}; 21 | 22 | // Valid Cipher Parameters 23 | const uint8_t simon_rounds[] = {32, 36, 36, 42, 44, 52, 54, 68, 69, 72}; 24 | const uint8_t z_assign[] = {0, 0, 1, 2, 3, 2, 3, 2, 3, 4}; 25 | 26 | void lw_simon_init(lw_simon_context *ctx, uint8_t block_size) 27 | { 28 | memset(ctx, 0, sizeof(lw_simon_context)); 29 | ctx->block_size = block_size; 30 | } 31 | 32 | void lw_simon_free(lw_simon_context *ctx) 33 | { 34 | memset(ctx, 0, sizeof(lw_simon_context)); 35 | } 36 | 37 | int lw_simon_setkey(lw_simon_context *ctx, const uint8_t *key, uint16_t key_bitlen) 38 | { 39 | ctx->key_bitlen = key_bitlen; 40 | switch (ctx->block_size) { 41 | case 4: 42 | if (ctx->key_bitlen != 64) 43 | return LW_ERR_SIMON_INVALID_CONFIG; 44 | ctx->round_limit = 32; 45 | ctx->encryptPtr = &Simon_Encrypt_32; 46 | ctx->decryptPtr = &Simon_Decrypt_32; 47 | break; 48 | case 6: 49 | if (ctx->key_bitlen != 72 && ctx->key_bitlen != 96) 50 | return LW_ERR_SIMON_INVALID_CONFIG; 51 | ctx->round_limit = 36; 52 | ctx->encryptPtr = Simon_Encrypt_48; 53 | ctx->decryptPtr = Simon_Decrypt_48; 54 | break; 55 | case 8: 56 | if (key_bitlen == 96) 57 | ctx->round_limit = 42; 58 | else if (key_bitlen == 128) 59 | ctx->round_limit = 44; 60 | else 61 | return LW_ERR_SIMON_INVALID_CONFIG; 62 | ctx->encryptPtr = Simon_Encrypt_64; 63 | ctx->decryptPtr = Simon_Decrypt_64; 64 | break; 65 | case 12: 66 | if (ctx->key_bitlen == 96) 67 | ctx->round_limit = 52; 68 | else if (ctx->key_bitlen == 144) 69 | ctx->round_limit = 54; 70 | else 71 | return LW_ERR_SIMON_INVALID_CONFIG; 72 | ctx->encryptPtr = Simon_Encrypt_96; 73 | ctx->decryptPtr = Simon_Decrypt_96; 74 | break; 75 | case 16: 76 | if (ctx->key_bitlen == 128) 77 | ctx->round_limit = 68; 78 | else if (ctx->key_bitlen == 192) 79 | ctx->round_limit = 69; 80 | else if (ctx->key_bitlen == 256) 81 | ctx->round_limit = 72; 82 | else 83 | return LW_ERR_SIMON_INVALID_CONFIG; 84 | ctx->encryptPtr = Simon_Encrypt_128; 85 | ctx->decryptPtr = Simon_Decrypt_128; 86 | break; 87 | default: 88 | return LW_ERR_SIMON_INVALID_CONFIG; 89 | } 90 | uint8_t word_size = ctx->block_size << 2; 91 | uint8_t word_bytes = word_size >> 3; 92 | uint16_t key_words = ctx->key_bitlen / word_size; 93 | uint64_t sub_keys[4] = {}; 94 | uint64_t mod_mask = ULLONG_MAX >> (64 - word_size); 95 | // Setup 96 | for (int i = 0; i < key_words; i++) { 97 | memcpy(&sub_keys[i], key + (word_bytes * i), word_bytes); 98 | } 99 | uint64_t tmp1, tmp2; 100 | uint64_t c = 0xFFFFFFFFFFFFFFFC; 101 | // Store First Key Schedule Entry 102 | memcpy(ctx->key_schedule, &sub_keys[0], word_bytes); 103 | for (int i = 0; i < ctx->round_limit - 1; i++) { 104 | tmp1 = rshift_three(sub_keys[key_words - 1]); 105 | 106 | if (key_words == 4) { 107 | tmp1 ^= sub_keys[1]; 108 | } 109 | 110 | tmp2 = rshift_one(tmp1); 111 | tmp1 ^= sub_keys[0]; 112 | tmp1 ^= tmp2; 113 | 114 | tmp2 = c ^ ((z_arrays[ctx->z_seq] >> (i % 62)) & 1); 115 | 116 | tmp1 ^= tmp2; 117 | 118 | // Shift Sub Words 119 | for (int j = 0; j < (key_words - 1); j++) { 120 | sub_keys[j] = sub_keys[j + 1]; 121 | } 122 | sub_keys[key_words - 1] = tmp1 & mod_mask; 123 | 124 | // Append sub key to key schedule 125 | memcpy(ctx->key_schedule + (word_bytes * (i + 1)), &sub_keys[0], word_bytes); 126 | 127 | } 128 | return 0; 129 | } 130 | 131 | int lw_simon_crypt_ecb(lw_simon_context *ctx, int mode, const uint8_t input[8], uint8_t output[8]) 132 | { 133 | if (mode != SIMON_ENCRYPT && mode != SIMON_DECRYPT) { 134 | return LW_ERR_SIMON_BAD_INPUT_DATA; 135 | } else if (ctx->round_limit == 0) { 136 | return LW_ERR_SIMON_INVALID_CONFIG; 137 | } else if (mode == SIMON_ENCRYPT) 138 | (*ctx->encryptPtr)(ctx->round_limit, ctx->key_schedule, input, output); 139 | else if (mode == SIMON_DECRYPT) 140 | (*ctx->decryptPtr)(ctx->round_limit, ctx->key_schedule, input, output); 141 | return 0; 142 | } 143 | 144 | int 145 | lw_simon_crypt_cbc(lw_simon_context *ctx, int mode, size_t length, uint8_t *iv, const uint8_t *input, uint8_t *output) 146 | { 147 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 148 | unsigned char *temp = (uint8_t *) malloc(ctx->block_size); 149 | if (mode != SIMON_ENCRYPT && mode != SIMON_DECRYPT) { 150 | return LW_ERR_SIMON_BAD_INPUT_DATA; 151 | } 152 | /* Nothing to do if length is zero. */ 153 | if (length == 0) { 154 | return 0; 155 | } 156 | if (length % ctx->block_size) { 157 | return LW_ERR_SIMON_INVALID_INPUT_LENGTH; 158 | } 159 | const unsigned char *ivp = iv; 160 | if (mode == SIMON_DECRYPT) { 161 | while (length > 0) { 162 | memcpy(temp, input, ctx->block_size); 163 | ret = lw_simon_crypt_ecb(ctx, mode, input, output); 164 | if (ret != 0) { 165 | return ret; 166 | } 167 | for (int i = 0; i < ctx->block_size; i++) { 168 | output[i] = iv[i] ^ output[i]; 169 | } 170 | memcpy(iv, temp, ctx->block_size); 171 | input += ctx->block_size; 172 | output += ctx->block_size; 173 | length -= ctx->block_size; 174 | } 175 | } else { 176 | while (length > 0) { 177 | for (int i = 0; i < ctx->block_size; i++) { 178 | output[i] = ivp[i] ^ input[i]; 179 | } 180 | ret = lw_simon_crypt_ecb(ctx, mode, output, output); 181 | if (ret != 0) { 182 | return ret; 183 | } 184 | ivp = output; 185 | input += ctx->block_size; 186 | output += ctx->block_size; 187 | length -= ctx->block_size; 188 | } 189 | memcpy(iv, ivp, ctx->block_size); 190 | } 191 | free(temp); 192 | ret = 0; 193 | return ret; 194 | } 195 | 196 | int 197 | lw_simon_crypt_ctr(lw_simon_context *ctx, size_t length, uint8_t *nc_off, uint8_t nonce_counter[8], 198 | uint8_t stream_block[8], 199 | const uint8_t *input, uint8_t *output) 200 | { 201 | int c, i; 202 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 203 | size_t n; 204 | n = *nc_off; 205 | if (n > ctx->block_size) { 206 | return LW_ERR_SIMON_BAD_INPUT_DATA; 207 | } 208 | while (length--) { 209 | if (n == 0) { 210 | ret = lw_simon_crypt_ecb(ctx, SIMON_ENCRYPT, nonce_counter, stream_block); 211 | if (ret != 0) { 212 | return ret; 213 | } 214 | for (i = ctx->block_size; i > 0; i--) { 215 | if (++nonce_counter[i - 1] != 0) { 216 | break; 217 | } 218 | } 219 | } 220 | c = *input++; 221 | *output++ = (unsigned char) (c ^ stream_block[n]); 222 | n = (n + 1) % ctx->block_size; 223 | } 224 | *nc_off = n; 225 | ret = 0; 226 | return ret; 227 | } 228 | 229 | #define print_hex(buffer, len) \ 230 | for (int i = 0; i < len; i++) { \ 231 | printf("%02x ", buffer[i]); \ 232 | } \ 233 | printf("\n"); 234 | 235 | int lw_simon_self_test(int verbose) 236 | { 237 | lw_simon_context ctx; 238 | uint8_t my_IV[] = {0x32, 0x14, 0x76, 0x58}; 239 | uint8_t my_counter[] = {0x2F, 0x3D, 0x5C, 0x7B}; 240 | uint8_t ciphertext_buffer[16]; 241 | uint8_t plaintext_buffer[16]; 242 | int ret; 243 | // Simon 64/32 Test 244 | // Key: 1918 1110 0908 0100 Plaintext: 6565 6877 Ciphertext: c69b e9bb 245 | { 246 | printf("**** Test Simon 64/32 ****\n"); 247 | { 248 | //ecb mode test 249 | uint8_t simon64_32_key[] = {0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19}; 250 | uint8_t simon64_32_plain[] = {0x77, 0x68, 0x65, 0x65}; 251 | lw_simon_init(&ctx, 4); 252 | ret = lw_simon_setkey(&ctx, simon64_32_key, 64); 253 | if (ret != 0) { 254 | printf("lw_simon_setkey error: %d\n", ret); 255 | return ret; 256 | } 257 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon64_32_plain, ciphertext_buffer); 258 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 259 | ret = memcmp(plaintext_buffer, simon64_32_plain, sizeof(simon64_32_plain)); 260 | if (ret != 0) { 261 | printf("ECB Test Failed!\n"); 262 | return ret; 263 | } else { 264 | printf("ECB Test Passed!\n"); 265 | } 266 | } 267 | { 268 | //cbc mode test 269 | uint8_t simon64_32_plain[] = {0x77, 0x68, 0x65, 0x65, 0x77, 0x68, 0x65, 0x65}; 270 | uint8_t simon64_32_key[] = {0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19}; 271 | lw_simon_init(&ctx, 4); 272 | ret = lw_simon_setkey(&ctx, simon64_32_key, 64); 273 | if (ret != 0) { 274 | printf("lw_simon_setkey error: %d\n", ret); 275 | return ret; 276 | } 277 | uint8_t iv[4] = {}; 278 | lw_simon_crypt_cbc(&ctx, SIMON_ENCRYPT, 8, iv, simon64_32_plain, ciphertext_buffer); 279 | memset(iv, 0, 4); 280 | lw_simon_crypt_cbc(&ctx, SIMON_DECRYPT, 8, iv, ciphertext_buffer, plaintext_buffer); 281 | ret = memcmp(plaintext_buffer, simon64_32_plain, sizeof(simon64_32_plain)); 282 | if (ret != 0) { 283 | printf("CBC Test Failed!\n"); 284 | return ret; 285 | } else { 286 | printf("CBC Test Passed!\n"); 287 | } 288 | } 289 | { 290 | //CTR mode test 291 | uint8_t simon64_32_plain[] = {0x77, 0x68, 0x65, 0x65, 0x77, 0x68, 0x65, 0x65}; 292 | uint8_t simon64_32_key[] = {0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19}; 293 | lw_simon_init(&ctx, 4); 294 | ret = lw_simon_setkey(&ctx, simon64_32_key, 64); 295 | if (ret != 0) { 296 | printf("lw_simon_setkey error: %d\n", ret); 297 | return ret; 298 | } 299 | uint8_t iv[4] = {}; 300 | uint8_t nc_off = 0; 301 | lw_simon_crypt_ctr(&ctx, 8, &nc_off, iv, my_counter, simon64_32_plain, ciphertext_buffer); 302 | memset(iv, 0, 4); 303 | lw_simon_crypt_ctr(&ctx, 8, &nc_off, iv, my_counter, ciphertext_buffer, plaintext_buffer); 304 | ret = memcmp(plaintext_buffer, simon64_32_plain, sizeof(simon64_32_plain)); 305 | if (ret != 0) { 306 | printf("CTR Test Failed!\n"); 307 | return ret; 308 | } else { 309 | printf("CTR Test Passed!\n"); 310 | } 311 | } 312 | } 313 | 314 | // Simon 72/48 Test 315 | // Key: 121110 0a0908 020100 Plaintext: 612067 6e696c Ciphertext: dae5ac 292cac 316 | { 317 | printf("**** Test Simon 72/48 ****\n"); 318 | { 319 | uint8_t simon72_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; 320 | uint8_t simon72_48_plain[] = {0x6c, 0x69, 0x6E, 0x67, 0x20, 0x61}; 321 | lw_simon_init(&ctx, 6); 322 | ret = lw_simon_setkey(&ctx, simon72_48_key, 72); 323 | if (ret != 0) { 324 | printf("lw_simon_setkey error: %d\n", ret); 325 | return ret; 326 | } 327 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon72_48_plain, ciphertext_buffer); 328 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 329 | ret = memcmp(plaintext_buffer, simon72_48_plain, sizeof(simon72_48_plain)); 330 | if (ret != 0) { 331 | printf("ECB Test Failed!\n"); 332 | return ret; 333 | } else { 334 | printf("ECB Test Passed!\n"); 335 | } 336 | } 337 | { 338 | // CBC mode test 339 | uint8_t simon72_48_plain[] = {0x6c, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x6c, 0x69, 0x6E, 0x67, 0x20, 0x61}; 340 | uint8_t simon72_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; 341 | lw_simon_init(&ctx, 6); 342 | ret = lw_simon_setkey(&ctx, simon72_48_key, 72); 343 | if (ret != 0) { 344 | printf("lw_simon_setkey error: %d\n", ret); 345 | return ret; 346 | } 347 | uint8_t iv[6] = {0}; 348 | lw_simon_crypt_cbc(&ctx, SIMON_ENCRYPT, 12, iv, simon72_48_plain, ciphertext_buffer); 349 | memset(iv, 0, 6); 350 | lw_simon_crypt_cbc(&ctx, SIMON_DECRYPT, 12, iv, ciphertext_buffer, plaintext_buffer); 351 | ret = memcmp(plaintext_buffer, simon72_48_plain, sizeof(simon72_48_plain)); 352 | if (ret != 0) { 353 | printf("CBC Test Failed!\n"); 354 | return ret; 355 | } else { 356 | printf("CBC Test Passed!\n"); 357 | } 358 | } 359 | } 360 | 361 | // Simon 96/48 Test 362 | // Key: 1a1918 121110 0a0908 020100 Plaintext: 726963 20646e Ciphertext: 6e06a5 acf156 363 | { 364 | printf("**** Test Simon 96/48 ****\n"); 365 | { 366 | uint8_t simon96_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12, 0x18, 0x19, 0x1a}; 367 | uint8_t simon96_48_plain[] = {0x6e, 0x64, 0x20, 0x63, 0x69, 0x72}; 368 | lw_simon_init(&ctx, 6); 369 | ret = lw_simon_setkey(&ctx, simon96_48_key, 96); 370 | if (ret != 0) { 371 | printf("lw_simon_setkey error: %d\n", ret); 372 | return ret; 373 | } 374 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon96_48_plain, ciphertext_buffer); 375 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 376 | ret = memcmp(plaintext_buffer, simon96_48_plain, sizeof(simon96_48_plain)); 377 | if (ret != 0) { 378 | printf("ECB Test Failed!\n"); 379 | return ret; 380 | } else { 381 | printf("ECB Test Passed!\n"); 382 | } 383 | } 384 | { 385 | // cbc mode test 386 | uint8_t simon96_48_plain[] = {0x6e, 0x64, 0x20, 0x63, 0x69, 0x72, 0x6e, 0x64, 0x20, 0x63, 0x69, 0x72}; 387 | uint8_t simon96_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12, 0x18, 0x19, 0x1a}; 388 | lw_simon_init(&ctx, 6); 389 | ret = lw_simon_setkey(&ctx, simon96_48_key, 96); 390 | if (ret != 0) { 391 | printf("lw_simon_setkey error: %d\n", ret); 392 | return ret; 393 | } 394 | uint8_t iv[6] = {0}; 395 | lw_simon_crypt_cbc(&ctx, SIMON_ENCRYPT, 12, iv, simon96_48_plain, ciphertext_buffer); 396 | memset(iv, 0, 6); 397 | lw_simon_crypt_cbc(&ctx, SIMON_DECRYPT, 12, iv, ciphertext_buffer, plaintext_buffer); 398 | ret = memcmp(plaintext_buffer, simon96_48_plain, sizeof(simon96_48_plain)); 399 | if (ret != 0) { 400 | printf("CBC Test Failed!\n"); 401 | return ret; 402 | } else { 403 | printf("CBC Test Passed!\n"); 404 | } 405 | } 406 | } 407 | 408 | 409 | // Simon 96/64 Test 410 | // Key: 13121110 0b0a0908 03020100 Plaintext: 6f722067 6e696c63 Ciphertext: 5ca2e27f 111a8fc8 411 | { 412 | printf("**** Test Simon 96/64 ****\n"); 413 | { 414 | uint8_t simon96_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13}; 415 | uint8_t simon96_64_plain[] = {0x63, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x6f}; 416 | lw_simon_init(&ctx, 8); 417 | ret = lw_simon_setkey(&ctx, simon96_64_key, 96); 418 | if (ret != 0) { 419 | printf("lw_simon_setkey error: %d\n", ret); 420 | return ret; 421 | } 422 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon96_64_plain, ciphertext_buffer); 423 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 424 | ret = memcmp(plaintext_buffer, simon96_64_plain, sizeof(simon96_64_plain)); 425 | if (ret != 0) { 426 | printf("ECB Test Failed!\n"); 427 | return ret; 428 | } else { 429 | printf("ECB Test Passed!\n"); 430 | } 431 | } 432 | { 433 | // cbc mode test 434 | uint8_t simon96_64_plain[] = {0x63, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x6f, 0x63, 0x6c, 0x69, 0x6e, 0x67, 435 | 0x20, 0x72, 0x6f}; 436 | uint8_t simon96_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13}; 437 | lw_simon_init(&ctx, 8); 438 | ret = lw_simon_setkey(&ctx, simon96_64_key, 96); 439 | if (ret != 0) { 440 | printf("lw_simon_setkey error: %d\n", ret); 441 | return ret; 442 | } 443 | uint8_t iv[8] = {0}; 444 | lw_simon_crypt_cbc(&ctx, SIMON_ENCRYPT, 16, iv, simon96_64_plain, ciphertext_buffer); 445 | memset(iv, 0, 8); 446 | lw_simon_crypt_cbc(&ctx, SIMON_DECRYPT, 16, iv, ciphertext_buffer, plaintext_buffer); 447 | ret = memcmp(plaintext_buffer, simon96_64_plain, sizeof(simon96_64_plain)); 448 | if (ret != 0) { 449 | printf("CBC Test Failed!\n"); 450 | return ret; 451 | } else { 452 | printf("CBC Test Passed!\n"); 453 | } 454 | } 455 | } 456 | 457 | 458 | // Simon 128/64 Test 459 | // Key: 1b1a1918 13121110 0b0a0908 03020100 Plaintext: 656b696c 20646e75 Ciphertext: 44c8fc20 b9dfa07a 460 | { 461 | printf("**** Test Simon 128/64 ****\n"); 462 | { 463 | uint8_t simon128_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13, 0x18, 464 | 0x19, 465 | 0x1A, 0x1B}; 466 | uint8_t simon128_64_plain[] = {0x75, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65}; 467 | lw_simon_init(&ctx, 8); 468 | ret = lw_simon_setkey(&ctx, simon128_64_key, 128); 469 | if (ret != 0) { 470 | printf("lw_simon_setkey error: %d\n", ret); 471 | return ret; 472 | } 473 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon128_64_plain, ciphertext_buffer); 474 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 475 | ret = memcmp(plaintext_buffer, simon128_64_plain, sizeof(simon128_64_plain)); 476 | if (ret != 0) { 477 | printf("ECB Test Failed!\n"); 478 | return ret; 479 | } else { 480 | printf("ECB Test Passed!\n"); 481 | } 482 | } 483 | { 484 | // CBC mode test 485 | uint8_t simon128_64_plain[] = {0x75, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x75, 0x6e, 0x64, 0x20, 0x6c, 486 | 0x69, 0x6b, 0x65}; 487 | uint8_t simon128_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13, 0x18, 488 | 0x19, 0x1A, 0x1B}; 489 | lw_simon_init(&ctx, 8); 490 | ret = lw_simon_setkey(&ctx, simon128_64_key, 128); 491 | if (ret != 0) { 492 | printf("lw_simon_setkey error: %d\n", ret); 493 | return ret; 494 | } 495 | uint8_t iv[8] = {0}; 496 | lw_simon_crypt_cbc(&ctx, SIMON_ENCRYPT, 16, iv, simon128_64_plain, ciphertext_buffer); 497 | memset(iv, 0, 8); 498 | lw_simon_crypt_cbc(&ctx, SIMON_DECRYPT, 16, iv, ciphertext_buffer, plaintext_buffer); 499 | ret = memcmp(plaintext_buffer, simon128_64_plain, sizeof(simon128_64_plain)); 500 | if (ret != 0) { 501 | printf("CBC Test Failed!\n"); 502 | return ret; 503 | } else { 504 | printf("CBC Test Passed!\n"); 505 | } 506 | } 507 | } 508 | 509 | 510 | // Simon 96/96 Test 511 | // Key: 0d0c0b0a0908 050403020100 Plaintext: 2072616c6c69 702065687420 Ciphertext: 602807a462b4 69063d8ff082 512 | { 513 | printf("**** Test Simon 96/96 ****\n"); 514 | { 515 | uint8_t simon96_96_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}; 516 | uint8_t simon96_96_plain[] = {0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x20}; 517 | lw_simon_init(&ctx, 12); 518 | ret = lw_simon_setkey(&ctx, simon96_96_key, 96); 519 | if (ret != 0) { 520 | printf("lw_simon_setkey error: %d\n", ret); 521 | return ret; 522 | } 523 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon96_96_plain, ciphertext_buffer); 524 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 525 | ret = memcmp(plaintext_buffer, simon96_96_plain, sizeof(simon96_96_plain)); 526 | if (ret != 0) { 527 | printf("ECB Test Failed!\n"); 528 | return ret; 529 | } else { 530 | printf("ECB Test Passed!\n"); 531 | } 532 | } 533 | { 534 | //CBC mode test 535 | uint8_t simon96_96_plain[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 536 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}; 537 | uint8_t simon96_96_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}; 538 | lw_simon_init(&ctx, 12); 539 | ret = lw_simon_setkey(&ctx, simon96_96_key, 96); 540 | if (ret != 0) { 541 | printf("lw_simon_setkey error: %d\n", ret); 542 | return ret; 543 | } 544 | uint8_t iv[12] = {0}; 545 | lw_simon_crypt_cbc(&ctx, SIMON_ENCRYPT, 24, iv, simon96_96_plain, ciphertext_buffer); 546 | memset(iv, 0, 12); 547 | lw_simon_crypt_cbc(&ctx, SIMON_DECRYPT, 24, iv, ciphertext_buffer, plaintext_buffer); 548 | ret = memcmp(plaintext_buffer, simon96_96_plain, sizeof(simon96_96_plain)); 549 | if (ret != 0) { 550 | printf("CBC Test Failed!\n"); 551 | return ret; 552 | } else { 553 | printf("CBC Test Passed!\n"); 554 | } 555 | } 556 | } 557 | 558 | 559 | // Simon 144/96 Test 560 | // Key: 151413121110 0d0c0b0a0908 050403020100 Plaintext: 746168742074 73756420666f Ciphertext: ecad1c6c451e 3f59c5db1ae9 561 | { 562 | printf("**** Test Simon 144/96 ****\n"); 563 | { 564 | uint8_t simon144_96_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x10, 565 | 0x11, 566 | 0x12, 0x13, 0x14, 0x15}; 567 | uint8_t simon144_96_plain[] = {0x6f, 0x66, 0x20, 0x64, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74}; 568 | lw_simon_init(&ctx, 12); 569 | ret = lw_simon_setkey(&ctx, simon144_96_key, 144); 570 | if (ret != 0) { 571 | printf("lw_simon_setkey error: %d\n", ret); 572 | return ret; 573 | } 574 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon144_96_plain, ciphertext_buffer); 575 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 576 | ret = memcmp(plaintext_buffer, simon144_96_plain, sizeof(simon144_96_plain)); 577 | if (ret != 0) { 578 | printf("ECB Test Failed!\n"); 579 | return ret; 580 | } else { 581 | printf("ECB Test Passed!\n"); 582 | } 583 | } 584 | { 585 | //CBC mode test 586 | uint8_t simon144_96_plain[] = {0x6f, 0x66, 0x20, 0x64, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 587 | 0x6f, 0x66, 0x20, 0x64, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74}; 588 | uint8_t simon144_96_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 589 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15}; 590 | lw_simon_init(&ctx, 12); 591 | ret = lw_simon_setkey(&ctx, simon144_96_key, 144); 592 | if (ret != 0) { 593 | printf("lw_simon_setkey error: %d\n", ret); 594 | return ret; 595 | } 596 | uint8_t iv[12] = {0}; 597 | lw_simon_crypt_cbc(&ctx, SIMON_ENCRYPT, 24, iv, simon144_96_plain, ciphertext_buffer); 598 | memset(iv, 0, 12); 599 | lw_simon_crypt_cbc(&ctx, SIMON_DECRYPT, 24, iv, ciphertext_buffer, plaintext_buffer); 600 | ret = memcmp(plaintext_buffer, simon144_96_plain, sizeof(simon144_96_plain)); 601 | if (ret != 0) { 602 | printf("CBC Test Failed!\n"); 603 | return ret; 604 | } else { 605 | printf("CBC Test Passed!\n"); 606 | } 607 | } 608 | } 609 | 610 | 611 | // Simon 128/128 Test 612 | // Key: 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 6373656420737265 6c6c657661727420 Ciphertext: 49681b1e1e54fe3f 65aa832af84e0bbc 613 | { 614 | printf("**** Test Simon 128/128 ****\n"); 615 | uint8_t simon128_128_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 616 | 0x0D, 0x0E, 0x0F}; 617 | uint8_t simon128_128_plain[] = {0x20, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x20, 0x64, 618 | 0x65, 0x73, 0x63}; 619 | lw_simon_init(&ctx, 16); 620 | ret = lw_simon_setkey(&ctx, simon128_128_key, 128); 621 | if (ret != 0) { 622 | printf("lw_simon_setkey error: %d\n", ret); 623 | return ret; 624 | } 625 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon128_128_plain, ciphertext_buffer); 626 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 627 | ret = memcmp(plaintext_buffer, simon128_128_plain, sizeof(simon128_128_plain)); 628 | if (ret != 0) { 629 | printf("Test Failed!\n"); 630 | return ret; 631 | } else { 632 | printf("Test Passed!\n"); 633 | } 634 | } 635 | 636 | 637 | // Simon 192/128 Test 638 | // Key: 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 206572656874206e 6568772065626972 Ciphertext: c4ac61effcdc0d4f 6c9c8d6e2597b85b 639 | { 640 | printf("**** Test Simon 192/128 ****\n"); 641 | uint8_t simon192_128_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 642 | 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; 643 | uint8_t simon192_128_plain[] = {0x72, 0x69, 0x62, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 644 | 0x72, 0x65, 0x20}; 645 | lw_simon_init(&ctx, 16); 646 | ret = lw_simon_setkey(&ctx, simon192_128_key, 192); 647 | if (ret != 0) { 648 | printf("lw_simon_setkey error: %d\n", ret); 649 | return ret; 650 | } 651 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon192_128_plain, ciphertext_buffer); 652 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 653 | ret = memcmp(plaintext_buffer, simon192_128_plain, sizeof(simon192_128_plain)); 654 | if (ret != 0) { 655 | printf("Test Failed!\n"); 656 | return ret; 657 | } else { 658 | printf("Test Passed!\n"); 659 | } 660 | } 661 | 662 | 663 | // Simon 256/128 Test 664 | // Key: 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 74206e69206d6f6f 6d69732061207369 Ciphertext: 8d2b5579afc8a3a0 3bf72a87efe7b868 665 | { 666 | printf("**** Test Simon 256/128 ****\n"); 667 | uint8_t simon256_128_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 668 | 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 669 | 0x1A, 0x1B, 0x1C, 0x1d, 0x1e, 0x1f}; 670 | uint8_t simon256_128_plain[] = {0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6d, 0x6f, 0x6f, 0x6d, 0x20, 0x69, 671 | 0x6e, 0x20, 0x74}; 672 | lw_simon_init(&ctx, 16); 673 | ret = lw_simon_setkey(&ctx, simon256_128_key, 256); 674 | if (ret != 0) { 675 | printf("lw_simon_setkey error: %d\n", ret); 676 | return ret; 677 | } 678 | lw_simon_crypt_ecb(&ctx, SIMON_ENCRYPT, simon256_128_plain, ciphertext_buffer); 679 | lw_simon_crypt_ecb(&ctx, SIMON_DECRYPT, ciphertext_buffer, plaintext_buffer); 680 | ret = memcmp(plaintext_buffer, simon256_128_plain, sizeof(simon256_128_plain)); 681 | if (ret != 0) { 682 | printf("Test Failed!\n"); 683 | return ret; 684 | } else { 685 | printf("Test Passed!\n"); 686 | } 687 | } 688 | return 0; 689 | } 690 | 691 | 692 | void 693 | Simon_Encrypt_32(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, uint8_t *ciphertext) 694 | { 695 | 696 | const uint8_t word_size = 16; 697 | uint16_t *y_word = (uint16_t *) ciphertext; 698 | uint16_t *x_word = (((uint16_t *) ciphertext) + 1); 699 | 700 | *y_word = *(uint16_t *) plaintext; 701 | *x_word = *(((uint16_t *) plaintext) + 1); 702 | 703 | uint16_t *round_key_ptr = (uint16_t *) key_schedule; 704 | 705 | for (uint8_t i = 0; i < round_limit; i++) { 706 | 707 | // Shift, AND , XOR ops 708 | uint16_t temp = (shift_one(*x_word) & shift_eight(*x_word)) ^ *y_word ^ shift_two(*x_word); 709 | 710 | // Feistel Cross 711 | *y_word = *x_word; 712 | 713 | // XOR with Round Key 714 | *x_word = temp ^ *(round_key_ptr + i); 715 | } 716 | } 717 | 718 | void Simon_Encrypt_48(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 719 | uint8_t *ciphertext) 720 | { 721 | 722 | const uint8_t word_size = 24; 723 | 724 | bword_24 intrd = *(bword_24 *) plaintext; 725 | uint32_t y_word = intrd.data; 726 | intrd = *((bword_24 *) (plaintext + 3)); 727 | uint32_t x_word = intrd.data; 728 | 729 | for (uint8_t i = 0; i < round_limit; i++) { 730 | 731 | // Shift, AND , XOR ops 732 | uint32_t temp = (shift_one(x_word) & shift_eight(x_word)) ^ y_word ^ shift_two(x_word); 733 | 734 | // Feistel Cross 735 | y_word = x_word; 736 | 737 | // XOR with Round Key 738 | x_word = (temp ^ (*((bword_24 *) (key_schedule + (i * 3)))).data) & 0xFFFFFF; 739 | } 740 | // Assemble Ciphertext Output Array 741 | intrd.data = y_word; 742 | bword_24 *intrd_ptr = (bword_24 *) ciphertext; 743 | *intrd_ptr = intrd; 744 | 745 | intrd.data = x_word; 746 | intrd_ptr = (bword_24 *) (ciphertext + 3); 747 | *intrd_ptr = intrd; 748 | } 749 | 750 | void Simon_Encrypt_64(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 751 | uint8_t *ciphertext) 752 | { 753 | 754 | const uint8_t word_size = 32; 755 | uint32_t *y_word = (uint32_t *) ciphertext; 756 | uint32_t *x_word = (((uint32_t *) ciphertext) + 1); 757 | *y_word = *(uint32_t *) plaintext; 758 | *x_word = *(((uint32_t *) plaintext) + 1); 759 | uint32_t *round_key_ptr = (uint32_t *) key_schedule; 760 | 761 | for (uint8_t i = 0; i < round_limit; i++) { 762 | 763 | // Shift, AND , XOR ops 764 | uint32_t temp = (shift_one(*x_word) & shift_eight(*x_word)) ^ *y_word ^ shift_two(*x_word); 765 | 766 | // Feistel Cross 767 | *y_word = *x_word; 768 | 769 | // XOR with Round Key 770 | *x_word = temp ^ *(round_key_ptr + i); 771 | } 772 | } 773 | 774 | void Simon_Encrypt_96(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 775 | uint8_t *ciphertext) 776 | { 777 | 778 | const uint8_t word_size = 48; 779 | 780 | bword_48 intrd = *(bword_48 *) plaintext; 781 | uint64_t y_word = intrd.data; 782 | intrd = *((bword_48 *) (plaintext + 6)); 783 | uint64_t x_word = intrd.data; 784 | 785 | for (uint8_t i = 0; i < round_limit; i++) { 786 | 787 | // Shift, AND , XOR ops 788 | uint64_t temp = (shift_one(x_word) & shift_eight(x_word)) ^ y_word ^ shift_two(x_word); 789 | 790 | // Feistel Cross 791 | y_word = x_word; 792 | 793 | // XOR with Round Key 794 | x_word = (temp ^ (*((bword_48 *) (key_schedule + (i * 6)))).data) & 0xFFFFFFFFFFFF; 795 | } 796 | // Assemble Ciphertext Output Array 797 | intrd.data = y_word; 798 | bword_48 *intrd_ptr = (bword_48 *) ciphertext; 799 | *intrd_ptr = intrd; 800 | 801 | intrd.data = x_word; 802 | intrd_ptr = (bword_48 *) (ciphertext + 6); 803 | *intrd_ptr = intrd; 804 | 805 | } 806 | 807 | void Simon_Encrypt_128(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 808 | uint8_t *ciphertext) 809 | { 810 | 811 | const uint8_t word_size = 64; 812 | uint64_t *y_word = (uint64_t *) ciphertext; 813 | uint64_t *x_word = (((uint64_t *) ciphertext) + 1); 814 | *y_word = *(uint64_t *) plaintext; 815 | *x_word = *(((uint64_t *) plaintext) + 1); 816 | uint64_t *round_key_ptr = (uint64_t *) key_schedule; 817 | 818 | 819 | for (uint8_t i = 0; i < round_limit; i++) { 820 | 821 | // Shift, AND , XOR ops 822 | uint64_t temp = (shift_one(*x_word) & shift_eight(*x_word)) ^ *y_word ^ shift_two(*x_word); 823 | 824 | // Feistel Cross 825 | *y_word = *x_word; 826 | 827 | // XOR with Round Key 828 | *x_word = temp ^ *(round_key_ptr + i); 829 | } 830 | } 831 | 832 | void Simon_Decrypt_32(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 833 | uint8_t *plaintext) 834 | { 835 | 836 | const uint8_t word_size = 16; 837 | uint16_t *x_word = (uint16_t *) plaintext; 838 | uint16_t *y_word = ((uint16_t *) plaintext) + 1; 839 | uint16_t *round_key_ptr = (uint16_t *) key_schedule; 840 | 841 | *x_word = *(uint16_t *) ciphertext; 842 | *y_word = *(((uint16_t *) ciphertext) + 1); 843 | 844 | for (int8_t i = round_limit - 1; i >= 0; i--) { 845 | 846 | // Shift, AND , XOR ops 847 | uint16_t temp = (shift_one(*x_word) & shift_eight(*x_word)) ^ *y_word ^ shift_two(*x_word); 848 | 849 | // Feistel Cross 850 | *y_word = *x_word; 851 | 852 | // XOR with Round Key 853 | *x_word = temp ^ *(round_key_ptr + i); 854 | } 855 | } 856 | 857 | void Simon_Decrypt_48(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 858 | uint8_t *plaintext) 859 | { 860 | const uint8_t word_size = 24; 861 | 862 | bword_24 intrd = *(bword_24 *) ciphertext; 863 | uint32_t x_word = intrd.data; 864 | intrd = *((bword_24 *) (ciphertext + 3)); 865 | uint32_t y_word = intrd.data; 866 | 867 | for (int8_t i = round_limit - 1; i >= 0; i--) { 868 | 869 | // Shift, AND , XOR ops 870 | uint32_t temp = (shift_one(x_word) & shift_eight(x_word)) ^ y_word ^ shift_two(x_word); 871 | 872 | // Feistel Cross 873 | y_word = x_word; 874 | 875 | // XOR with Round Key 876 | x_word = (temp ^ (*((bword_24 *) (key_schedule + (i * 3)))).data) & 0xFFFFFF; 877 | } 878 | // Assemble plaintext Output Array 879 | intrd.data = x_word; 880 | bword_24 *intrd_ptr = (bword_24 *) plaintext; 881 | *intrd_ptr = intrd; 882 | 883 | intrd.data = y_word; 884 | intrd_ptr = (bword_24 *) (plaintext + 3); 885 | *intrd_ptr = intrd; 886 | } 887 | 888 | void Simon_Decrypt_64(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 889 | uint8_t *plaintext) 890 | { 891 | 892 | const uint8_t word_size = 32; 893 | uint32_t *x_word = (uint32_t *) plaintext; 894 | uint32_t *y_word = ((uint32_t *) plaintext) + 1; 895 | uint32_t *round_key_ptr = (uint32_t *) key_schedule; 896 | 897 | *x_word = *(uint32_t *) ciphertext; 898 | *y_word = *(((uint32_t *) ciphertext) + 1); 899 | 900 | for (int8_t i = round_limit - 1; i >= 0; i--) { 901 | 902 | // Shift, AND , XOR ops 903 | uint32_t temp = (shift_one(*x_word) & shift_eight(*x_word)) ^ *y_word ^ shift_two(*x_word); 904 | 905 | // Feistel Cross 906 | *y_word = *x_word; 907 | 908 | // XOR with Round Key 909 | *x_word = temp ^ *(round_key_ptr + i); 910 | } 911 | } 912 | 913 | void Simon_Decrypt_96(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 914 | uint8_t *plaintext) 915 | { 916 | const uint8_t word_size = 48; 917 | bword_48 intrd = *(bword_48 *) ciphertext; 918 | uint64_t x_word = intrd.data; 919 | intrd = *((bword_48 *) (ciphertext + 6)); 920 | uint64_t y_word = intrd.data; 921 | 922 | for (int8_t i = round_limit - 1; i >= 0; i--) { 923 | 924 | // Shift, AND , XOR ops 925 | uint64_t temp = (shift_one(x_word) & shift_eight(x_word)) ^ y_word ^ shift_two(x_word); 926 | 927 | // Feistel Cross 928 | y_word = x_word; 929 | 930 | // XOR with Round Key 931 | x_word = (temp ^ (*((bword_48 *) (key_schedule + (i * 6)))).data) & 0xFFFFFFFFFFFF; 932 | } 933 | // Assemble Plaintext Output Array 934 | intrd.data = x_word; 935 | bword_48 *intrd_ptr = (bword_48 *) plaintext; 936 | *intrd_ptr = intrd; 937 | 938 | intrd.data = y_word; 939 | intrd_ptr = (bword_48 *) (plaintext + 6); 940 | *intrd_ptr = intrd; 941 | } 942 | 943 | void Simon_Decrypt_128(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 944 | uint8_t *plaintext) 945 | { 946 | 947 | const uint8_t word_size = 64; 948 | uint64_t *x_word = (uint64_t *) plaintext; 949 | uint64_t *y_word = ((uint64_t *) plaintext) + 1; 950 | uint64_t *round_key_ptr = (uint64_t *) key_schedule; 951 | 952 | *x_word = *(uint64_t *) ciphertext; 953 | *y_word = *(((uint64_t *) ciphertext) + 1); 954 | 955 | for (int8_t i = round_limit - 1; i >= 0; i--) { 956 | 957 | // Shift, AND , XOR ops 958 | uint64_t temp = (shift_one(*x_word) & shift_eight(*x_word)) ^ *y_word ^ shift_two(*x_word); 959 | 960 | // Feistel Cross 961 | *y_word = *x_word; 962 | 963 | // XOR with Round Key 964 | *x_word = temp ^ *(round_key_ptr + i); 965 | } 966 | } -------------------------------------------------------------------------------- /src/speck.c: -------------------------------------------------------------------------------- 1 | #include "speck.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "speck.h" 8 | 9 | 10 | #define rotate_left(x, n) (((x) >> (word_size - (n))) | ((x) << (n))) 11 | #define rotate_right(x, n) (((x) << (word_size - (n))) | ((x) >> (n))) 12 | 13 | const uint8_t speck_rounds[] = {22, 22, 23, 26, 27, 28, 29, 32, 33, 34}; 14 | 15 | void lw_speck_init(lw_speck_context *ctx, uint8_t block_size) 16 | { 17 | memset(ctx, 0, sizeof(lw_speck_context)); 18 | ctx->block_size = block_size; 19 | } 20 | 21 | void lw_speck_free(lw_speck_context *ctx) 22 | { 23 | memset(ctx, 0, sizeof(lw_speck_context)); 24 | } 25 | 26 | int lw_speck_setkey(lw_speck_context *ctx, const uint8_t *key, uint16_t key_bitlen) 27 | { 28 | ctx->key_bitlen = key_bitlen; 29 | switch (ctx->block_size) { 30 | case 4: 31 | if (ctx->key_bitlen != 64) { 32 | return LW_ERR_SPECK_INVALID_CONFIG; 33 | } 34 | ctx->round_limit = 22; 35 | ctx->encryptPtr = &Speck_Encrypt_32; 36 | ctx->decryptPtr = &Speck_Decrypt_32; 37 | break; 38 | case 6: 39 | if (ctx->key_bitlen == 72) 40 | ctx->round_limit = 22; 41 | else if (ctx->key_bitlen == 96) 42 | ctx->round_limit = 23; 43 | else 44 | return LW_ERR_SPECK_INVALID_CONFIG; 45 | ctx->encryptPtr = &Speck_Encrypt_48; 46 | ctx->decryptPtr = &Speck_Decrypt_48; 47 | break; 48 | case 8: 49 | if (ctx->key_bitlen == 96) 50 | ctx->round_limit = 26; 51 | else if (ctx->key_bitlen == 128) 52 | ctx->round_limit = 27; 53 | else 54 | return LW_ERR_SPECK_INVALID_CONFIG; 55 | ctx->encryptPtr = &Speck_Encrypt_64; 56 | ctx->decryptPtr = &Speck_Decrypt_64; 57 | break; 58 | case 12: 59 | if (ctx->key_bitlen == 96) 60 | ctx->round_limit = 28; 61 | else if (ctx->key_bitlen == 144) 62 | ctx->round_limit = 29; 63 | else 64 | return LW_ERR_SPECK_INVALID_CONFIG; 65 | ctx->encryptPtr = &Speck_Encrypt_96; 66 | ctx->decryptPtr = &Speck_Decrypt_96; 67 | break; 68 | case 16: 69 | if (ctx->key_bitlen == 128) 70 | ctx->round_limit = 32; 71 | else if (ctx->key_bitlen == 192) 72 | ctx->round_limit = 33; 73 | else if (ctx->key_bitlen == 256) 74 | ctx->round_limit = 34; 75 | else 76 | return LW_ERR_SPECK_INVALID_CONFIG; 77 | ctx->encryptPtr = &Speck_Encrypt_128; 78 | ctx->decryptPtr = &Speck_Decrypt_128; 79 | break; 80 | default: 81 | return LW_ERR_SPECK_INVALID_CONFIG; 82 | } 83 | uint8_t word_size = ctx->block_size << 2; 84 | uint8_t word_bytes = word_size >> 3; 85 | uint16_t key_words = ctx->key_bitlen / word_size; 86 | uint64_t sub_keys[4] = {}; 87 | uint64_t mod_mask = ULLONG_MAX >> (64 - word_size); 88 | // Setup 89 | for (int i = 0; i < key_words; i++) { 90 | memcpy(&sub_keys[i], key + (word_bytes * i), word_bytes); 91 | } 92 | uint64_t tmp1, tmp2; 93 | for (uint64_t i = 0; i < ctx->round_limit - 1; i++) { 94 | 95 | // Run Speck Cipher Round Function 96 | tmp1 = (rotate_right(sub_keys[1],ctx->alpha)) & mod_mask; 97 | tmp1 = (tmp1 + sub_keys[0]) & mod_mask; 98 | tmp1= tmp1 ^ i; 99 | tmp2 = (rotate_left(sub_keys[0],ctx->beta)) & mod_mask; 100 | tmp2 = tmp2 ^ tmp1; 101 | sub_keys[0] = tmp2; 102 | 103 | // Shift Key Schedule Subword 104 | if (key_words != 2) { 105 | // Shift Sub Words 106 | for(int j = 1; j < (key_words - 1); j++){ 107 | sub_keys[j] = sub_keys[j+1]; 108 | } 109 | } 110 | sub_keys[key_words - 1] = tmp1; 111 | 112 | // Append sub key to key schedule 113 | memcpy(ctx->key_schedule + (word_bytes * (i+1)), &sub_keys[0], word_bytes); 114 | } 115 | return 0; 116 | } 117 | 118 | int lw_speck_crypt_ecb(lw_speck_context *ctx, int mode, const uint8_t *input, uint8_t *output) 119 | { 120 | if (mode != SPECK_ENCRYPT && mode != SPECK_DECRYPT) { 121 | return LW_ERR_SPECK_BAD_INPUT_DATA; 122 | }else if(ctx->key_bitlen == 0 || ctx->block_size == 0){ 123 | return LW_ERR_SPECK_INVALID_CONFIG; 124 | }else if (mode == SPECK_ENCRYPT) { 125 | (*ctx->encryptPtr)(ctx->round_limit, ctx->key_schedule, input, output); 126 | } else { 127 | (*ctx->decryptPtr)(ctx->round_limit, ctx->key_schedule, input, output); 128 | } 129 | return 0; 130 | } 131 | 132 | int 133 | lw_speck_crypt_cbc(lw_speck_context *ctx, int mode, size_t length, uint8_t *iv, const uint8_t *input, uint8_t *output) 134 | { 135 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 136 | unsigned char *temp = (uint8_t*)malloc(ctx->block_size); 137 | if (mode != SPECK_ENCRYPT && mode != SPECK_DECRYPT) { 138 | return LW_ERR_SPECK_BAD_INPUT_DATA; 139 | } 140 | /* Nothing to do if length is zero. */ 141 | if (length == 0) { 142 | return 0; 143 | } 144 | if (length % ctx->block_size) { 145 | return LW_ERR_SPECK_INVALID_INPUT_LENGTH; 146 | } 147 | const unsigned char *ivp = iv; 148 | if (mode == SPECK_DECRYPT) { 149 | while (length > 0) { 150 | memcpy(temp, input, ctx->block_size); 151 | ret = lw_speck_crypt_ecb(ctx, mode, input, output); 152 | if (ret != 0) { 153 | return ret; 154 | } 155 | for (int i = 0; i < ctx->block_size; i++) { 156 | output[i] = iv[i] ^ output[i]; 157 | } 158 | memcpy(iv, temp, ctx->block_size); 159 | input += ctx->block_size; 160 | output += ctx->block_size; 161 | length -= ctx->block_size; 162 | } 163 | } else { 164 | while (length > 0) { 165 | for (int i = 0; i < ctx->block_size; i++) { 166 | output[i] = ivp[i] ^ input[i]; 167 | } 168 | ret = lw_speck_crypt_ecb(ctx, mode, output, output); 169 | if (ret != 0) { 170 | return ret; 171 | } 172 | ivp = output; 173 | input += ctx->block_size; 174 | output += ctx->block_size; 175 | length -= ctx->block_size; 176 | } 177 | memcpy(iv, ivp, ctx->block_size); 178 | } 179 | free(temp); 180 | ret = 0; 181 | return ret; 182 | return 0; 183 | } 184 | 185 | int 186 | lw_speck_crypt_ctr(lw_speck_context *ctx, size_t length, uint8_t *nc_off, uint8_t nonce_counter[8], 187 | uint8_t stream_block[8], 188 | const uint8_t *input, uint8_t *output) 189 | { 190 | int c, i; 191 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 192 | size_t n; 193 | n = *nc_off; 194 | if (n > ctx->block_size) { 195 | return LW_ERR_SPECK_BAD_INPUT_DATA; 196 | } 197 | while (length--) { 198 | if (n == 0) { 199 | ret = lw_speck_crypt_ecb(ctx, SPECK_ENCRYPT, nonce_counter, stream_block); 200 | if (ret != 0) { 201 | return ret; 202 | } 203 | for (i = ctx->block_size; i > 0; i--) { 204 | if (++nonce_counter[i - 1] != 0) { 205 | break; 206 | } 207 | } 208 | } 209 | c = *input++; 210 | *output++ = (unsigned char) (c ^ stream_block[n]); 211 | n = (n + 1) % ctx->block_size; 212 | } 213 | *nc_off = n; 214 | ret = 0; 215 | return ret; 216 | } 217 | #define print_hex(buffer, len) \ 218 | for (int i = 0; i < len; i++) { \ 219 | printf("%02x ", buffer[i]); \ 220 | } \ 221 | printf("\n"); 222 | 223 | int lw_speck_self_test(int verbose) 224 | 225 | { 226 | lw_speck_context ctx; 227 | uint8_t my_IV[] = {0x32, 0x14, 0x76, 0x58}; 228 | uint8_t my_counter[] = {0x2F, 0x3D, 0x5C, 0x7B}; 229 | uint8_t ciphertext_buffer[16]; 230 | uint8_t plaintext_buffer[16]; 231 | int ret; 232 | // Speck 64/32 Test 233 | // Key: 1918 1110 0908 0100 Plaintext: 6565 6877 Ciphertext: c69b e9bb 234 | { 235 | printf("**** Test Speck 64/32 ****\n"); 236 | { 237 | //ecb mode test 238 | uint8_t speck64_32_key[] = {0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19}; 239 | uint8_t speck64_32_plain[] = {0x77, 0x68, 0x65, 0x65}; 240 | lw_speck_init(&ctx, 4); 241 | ret = lw_speck_setkey(&ctx, speck64_32_key, 64); 242 | if (ret != 0) { 243 | printf("lw_speck_setkey error: %d\n", ret); 244 | return ret; 245 | } 246 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck64_32_plain, ciphertext_buffer); 247 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 248 | ret = memcmp(plaintext_buffer, speck64_32_plain, sizeof(speck64_32_plain)); 249 | if (ret != 0) { 250 | printf("ECB Test Failed!\n"); 251 | return ret; 252 | } else { 253 | printf("ECB Test Passed!\n"); 254 | } 255 | } 256 | { 257 | //cbc mode test 258 | uint8_t speck64_32_plain[] = {0x77, 0x68, 0x65, 0x65, 0x77, 0x68, 0x65, 0x65}; 259 | uint8_t speck64_32_key[] = {0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19}; 260 | lw_speck_init(&ctx, 4); 261 | ret = lw_speck_setkey(&ctx, speck64_32_key, 64); 262 | if (ret != 0) { 263 | printf("lw_speck_setkey error: %d\n", ret); 264 | return ret; 265 | } 266 | uint8_t iv[4] = {}; 267 | lw_speck_crypt_cbc(&ctx, SPECK_ENCRYPT, 8, iv, speck64_32_plain, ciphertext_buffer); 268 | memset(iv, 0, 4); 269 | lw_speck_crypt_cbc(&ctx, SPECK_DECRYPT, 8, iv, ciphertext_buffer, plaintext_buffer); 270 | ret = memcmp(plaintext_buffer, speck64_32_plain, sizeof(speck64_32_plain)); 271 | if (ret != 0) { 272 | printf("CBC Test Failed!\n"); 273 | return ret; 274 | } else { 275 | printf("CBC Test Passed!\n"); 276 | } 277 | } 278 | { 279 | //CTR mode test 280 | uint8_t speck64_32_plain[] = {0x77, 0x68, 0x65, 0x65, 0x77, 0x68, 0x65, 0x65}; 281 | uint8_t speck64_32_key[] = {0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19}; 282 | lw_speck_init(&ctx, 4); 283 | ret = lw_speck_setkey(&ctx, speck64_32_key, 64); 284 | if (ret != 0) { 285 | printf("lw_speck_setkey error: %d\n", ret); 286 | return ret; 287 | } 288 | uint8_t iv[4] = {}; 289 | uint8_t nc_off = 0; 290 | lw_speck_crypt_ctr(&ctx, 8,&nc_off, iv, my_counter, speck64_32_plain, ciphertext_buffer); 291 | memset(iv, 0, 4); 292 | lw_speck_crypt_ctr(&ctx, 8, &nc_off, iv, my_counter, ciphertext_buffer, plaintext_buffer); 293 | ret = memcmp(plaintext_buffer, speck64_32_plain, sizeof(speck64_32_plain)); 294 | if (ret != 0) { 295 | printf("CTR Test Failed!\n"); 296 | return ret; 297 | } else { 298 | printf("CTR Test Passed!\n"); 299 | } 300 | } 301 | } 302 | 303 | // Speck 72/48 Test 304 | // Key: 121110 0a0908 020100 Plaintext: 612067 6e696c Ciphertext: dae5ac 292cac 305 | { 306 | printf("**** Test Speck 72/48 ****\n"); 307 | { 308 | uint8_t speck72_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; 309 | uint8_t speck72_48_plain[] = {0x6c, 0x69, 0x6E, 0x67, 0x20, 0x61}; 310 | lw_speck_init(&ctx, 6); 311 | ret = lw_speck_setkey(&ctx, speck72_48_key, 72); 312 | if (ret != 0) { 313 | printf("lw_speck_setkey error: %d\n", ret); 314 | return ret; 315 | } 316 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck72_48_plain, ciphertext_buffer); 317 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 318 | ret = memcmp(plaintext_buffer, speck72_48_plain, sizeof(speck72_48_plain)); 319 | if (ret != 0) { 320 | printf("ECB Test Failed!\n"); 321 | return ret; 322 | } else { 323 | printf("ECB Test Passed!\n"); 324 | } 325 | } 326 | { 327 | // CBC mode test 328 | uint8_t speck72_48_plain[] = {0x6c, 0x69, 0x6E, 0x67, 0x20, 0x61,0x6c, 0x69, 0x6E, 0x67, 0x20, 0x61}; 329 | uint8_t speck72_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; 330 | lw_speck_init(&ctx, 6); 331 | ret = lw_speck_setkey(&ctx, speck72_48_key, 72); 332 | if (ret != 0) { 333 | printf("lw_speck_setkey error: %d\n", ret); 334 | return ret; 335 | } 336 | uint8_t iv[6] = {0}; 337 | lw_speck_crypt_cbc(&ctx, SPECK_ENCRYPT, 12, iv, speck72_48_plain, ciphertext_buffer); 338 | memset(iv, 0, 6); 339 | lw_speck_crypt_cbc(&ctx, SPECK_DECRYPT, 12, iv, ciphertext_buffer, plaintext_buffer); 340 | ret = memcmp(plaintext_buffer, speck72_48_plain, sizeof(speck72_48_plain)); 341 | if (ret != 0) { 342 | printf("CBC Test Failed!\n"); 343 | return ret; 344 | } else { 345 | printf("CBC Test Passed!\n"); 346 | } 347 | } 348 | } 349 | 350 | // Speck 96/48 Test 351 | // Key: 1a1918 121110 0a0908 020100 Plaintext: 726963 20646e Ciphertext: 6e06a5 acf156 352 | { 353 | printf("**** Test Speck 96/48 ****\n"); 354 | { 355 | uint8_t speck96_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12, 0x18, 0x19, 0x1a}; 356 | uint8_t speck96_48_plain[] = {0x6e, 0x64, 0x20, 0x63, 0x69, 0x72}; 357 | lw_speck_init(&ctx, 6); 358 | ret = lw_speck_setkey(&ctx, speck96_48_key, 96); 359 | if (ret != 0) { 360 | printf("lw_speck_setkey error: %d\n", ret); 361 | return ret; 362 | } 363 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck96_48_plain, ciphertext_buffer); 364 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 365 | ret = memcmp(plaintext_buffer, speck96_48_plain, sizeof(speck96_48_plain)); 366 | if (ret != 0) { 367 | printf("ECB Test Failed!\n"); 368 | return ret; 369 | } else { 370 | printf("ECB Test Passed!\n"); 371 | } 372 | } 373 | { 374 | // cbc mode test 375 | uint8_t speck96_48_plain[] = {0x6e, 0x64, 0x20, 0x63, 0x69, 0x72, 0x6e, 0x64, 0x20, 0x63, 0x69, 0x72}; 376 | uint8_t speck96_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12, 0x18, 0x19, 0x1a}; 377 | lw_speck_init(&ctx, 6); 378 | ret = lw_speck_setkey(&ctx, speck96_48_key, 96); 379 | if (ret != 0) { 380 | printf("lw_speck_setkey error: %d\n", ret); 381 | return ret; 382 | } 383 | uint8_t iv[6] = {0}; 384 | lw_speck_crypt_cbc(&ctx, SPECK_ENCRYPT, 12, iv, speck96_48_plain, ciphertext_buffer); 385 | memset(iv, 0, 6); 386 | lw_speck_crypt_cbc(&ctx, SPECK_DECRYPT, 12, iv, ciphertext_buffer, plaintext_buffer); 387 | ret = memcmp(plaintext_buffer, speck96_48_plain, sizeof(speck96_48_plain)); 388 | if (ret != 0) { 389 | printf("CBC Test Failed!\n"); 390 | return ret; 391 | } else { 392 | printf("CBC Test Passed!\n"); 393 | } 394 | } 395 | } 396 | 397 | 398 | // Speck 96/64 Test 399 | // Key: 13121110 0b0a0908 03020100 Plaintext: 6f722067 6e696c63 Ciphertext: 5ca2e27f 111a8fc8 400 | { 401 | printf("**** Test Speck 96/64 ****\n"); 402 | { 403 | uint8_t speck96_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13}; 404 | uint8_t speck96_64_plain[] = {0x63, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x6f}; 405 | lw_speck_init(&ctx, 8); 406 | ret = lw_speck_setkey(&ctx, speck96_64_key, 96); 407 | if (ret != 0) { 408 | printf("lw_speck_setkey error: %d\n", ret); 409 | return ret; 410 | } 411 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck96_64_plain, ciphertext_buffer); 412 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 413 | ret = memcmp(plaintext_buffer, speck96_64_plain, sizeof(speck96_64_plain)); 414 | if (ret != 0) { 415 | printf("ECB Test Failed!\n"); 416 | return ret; 417 | } else { 418 | printf("ECB Test Passed!\n"); 419 | } 420 | } 421 | { 422 | // cbc mode test 423 | uint8_t speck96_64_plain[] = {0x63, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x6f, 0x63, 0x6c, 0x69, 0x6e, 0x67, 424 | 0x20, 0x72, 0x6f}; 425 | uint8_t speck96_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13}; 426 | lw_speck_init(&ctx, 8); 427 | ret = lw_speck_setkey(&ctx, speck96_64_key, 96); 428 | if (ret != 0) { 429 | printf("lw_speck_setkey error: %d\n", ret); 430 | return ret; 431 | } 432 | uint8_t iv[8] = {0}; 433 | lw_speck_crypt_cbc(&ctx, SPECK_ENCRYPT, 16, iv, speck96_64_plain, ciphertext_buffer); 434 | memset(iv, 0, 8); 435 | lw_speck_crypt_cbc(&ctx, SPECK_DECRYPT, 16, iv, ciphertext_buffer, plaintext_buffer); 436 | ret = memcmp(plaintext_buffer, speck96_64_plain, sizeof(speck96_64_plain)); 437 | if (ret != 0) { 438 | printf("CBC Test Failed!\n"); 439 | return ret; 440 | } else { 441 | printf("CBC Test Passed!\n"); 442 | } 443 | } 444 | } 445 | 446 | 447 | // Speck 128/64 Test 448 | // Key: 1b1a1918 13121110 0b0a0908 03020100 Plaintext: 656b696c 20646e75 Ciphertext: 44c8fc20 b9dfa07a 449 | { 450 | printf("**** Test Speck 128/64 ****\n"); 451 | { 452 | uint8_t speck128_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 453 | 0x1A, 0x1B}; 454 | uint8_t speck128_64_plain[] = {0x75, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65}; 455 | lw_speck_init(&ctx, 8); 456 | ret = lw_speck_setkey(&ctx, speck128_64_key, 128); 457 | if (ret != 0) { 458 | printf("lw_speck_setkey error: %d\n", ret); 459 | return ret; 460 | } 461 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck128_64_plain, ciphertext_buffer); 462 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 463 | ret = memcmp(plaintext_buffer, speck128_64_plain, sizeof(speck128_64_plain)); 464 | if (ret != 0) { 465 | printf("ECB Test Failed!\n"); 466 | return ret; 467 | } else { 468 | printf("ECB Test Passed!\n"); 469 | } 470 | } 471 | { 472 | // CBC mode test 473 | uint8_t speck128_64_plain[] = {0x75, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x75, 0x6e, 0x64, 0x20, 0x6c, 474 | 0x69, 0x6b, 0x65}; 475 | uint8_t speck128_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13, 0x18, 476 | 0x19, 0x1A, 0x1B}; 477 | lw_speck_init(&ctx, 8); 478 | ret = lw_speck_setkey(&ctx, speck128_64_key, 128); 479 | if (ret != 0) { 480 | printf("lw_speck_setkey error: %d\n", ret); 481 | return ret; 482 | } 483 | uint8_t iv[8] = {0}; 484 | lw_speck_crypt_cbc(&ctx, SPECK_ENCRYPT, 16, iv, speck128_64_plain, ciphertext_buffer); 485 | memset(iv, 0, 8); 486 | lw_speck_crypt_cbc(&ctx, SPECK_DECRYPT, 16, iv, ciphertext_buffer, plaintext_buffer); 487 | ret = memcmp(plaintext_buffer, speck128_64_plain, sizeof(speck128_64_plain)); 488 | if (ret != 0) { 489 | printf("CBC Test Failed!\n"); 490 | return ret; 491 | } else { 492 | printf("CBC Test Passed!\n"); 493 | } 494 | } 495 | } 496 | 497 | 498 | // Speck 96/96 Test 499 | // Key: 0d0c0b0a0908 050403020100 Plaintext: 2072616c6c69 702065687420 Ciphertext: 602807a462b4 69063d8ff082 500 | { 501 | printf("**** Test Speck 96/96 ****\n"); 502 | { 503 | uint8_t speck96_96_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}; 504 | uint8_t speck96_96_plain[] = {0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x20}; 505 | lw_speck_init(&ctx, 12); 506 | ret = lw_speck_setkey(&ctx, speck96_96_key, 96); 507 | if (ret != 0) { 508 | printf("lw_speck_setkey error: %d\n", ret); 509 | return ret; 510 | } 511 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck96_96_plain, ciphertext_buffer); 512 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 513 | ret = memcmp(plaintext_buffer, speck96_96_plain, sizeof(speck96_96_plain)); 514 | if (ret != 0) { 515 | printf("ECB Test Failed!\n"); 516 | return ret; 517 | } else { 518 | printf("ECB Test Passed!\n"); 519 | } 520 | } 521 | { 522 | //CBC mode test 523 | uint8_t speck96_96_plain[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 524 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}; 525 | uint8_t speck96_96_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}; 526 | lw_speck_init(&ctx, 12); 527 | ret = lw_speck_setkey(&ctx, speck96_96_key, 96); 528 | if (ret != 0) { 529 | printf("lw_speck_setkey error: %d\n", ret); 530 | return ret; 531 | } 532 | uint8_t iv[12] = {0}; 533 | lw_speck_crypt_cbc(&ctx, SPECK_ENCRYPT, 24, iv, speck96_96_plain, ciphertext_buffer); 534 | memset(iv, 0, 12); 535 | lw_speck_crypt_cbc(&ctx, SPECK_DECRYPT, 24, iv, ciphertext_buffer, plaintext_buffer); 536 | ret = memcmp(plaintext_buffer, speck96_96_plain, sizeof(speck96_96_plain)); 537 | if (ret != 0) { 538 | printf("CBC Test Failed!\n"); 539 | return ret; 540 | } else { 541 | printf("CBC Test Passed!\n"); 542 | } 543 | } 544 | } 545 | 546 | 547 | // Speck 144/96 Test 548 | // Key: 151413121110 0d0c0b0a0908 050403020100 Plaintext: 746168742074 73756420666f Ciphertext: ecad1c6c451e 3f59c5db1ae9 549 | { 550 | printf("**** Test Speck 144/96 ****\n"); 551 | { 552 | uint8_t speck144_96_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x10, 0x11, 553 | 0x12, 0x13, 0x14, 0x15}; 554 | uint8_t speck144_96_plain[] = {0x6f, 0x66, 0x20, 0x64, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74}; 555 | lw_speck_init(&ctx, 12); 556 | ret = lw_speck_setkey(&ctx, speck144_96_key, 144); 557 | if (ret != 0) { 558 | printf("lw_speck_setkey error: %d\n", ret); 559 | return ret; 560 | } 561 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck144_96_plain, ciphertext_buffer); 562 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 563 | ret = memcmp(plaintext_buffer, speck144_96_plain, sizeof(speck144_96_plain)); 564 | if (ret != 0) { 565 | printf("ECB Test Failed!\n"); 566 | return ret; 567 | } else { 568 | printf("ECB Test Passed!\n"); 569 | } 570 | } 571 | { 572 | //CBC mode test 573 | uint8_t speck144_96_plain[] = {0x6f, 0x66, 0x20, 0x64, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 574 | 0x6f, 0x66, 0x20, 0x64, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74}; 575 | uint8_t speck144_96_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 576 | 0x10, 0x11, 0x12, 0x13,0x14, 0x15}; 577 | lw_speck_init(&ctx, 12); 578 | ret = lw_speck_setkey(&ctx, speck144_96_key, 144); 579 | if (ret != 0) { 580 | printf("lw_speck_setkey error: %d\n", ret); 581 | return ret; 582 | } 583 | uint8_t iv[12] = {0}; 584 | lw_speck_crypt_cbc(&ctx, SPECK_ENCRYPT, 24, iv, speck144_96_plain, ciphertext_buffer); 585 | memset(iv, 0, 12); 586 | lw_speck_crypt_cbc(&ctx, SPECK_DECRYPT, 24, iv, ciphertext_buffer, plaintext_buffer); 587 | ret = memcmp(plaintext_buffer, speck144_96_plain, sizeof(speck144_96_plain)); 588 | if (ret != 0) { 589 | printf("CBC Test Failed!\n"); 590 | return ret; 591 | } else { 592 | printf("CBC Test Passed!\n"); 593 | } 594 | } 595 | } 596 | 597 | 598 | // Speck 128/128 Test 599 | // Key: 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 6373656420737265 6c6c657661727420 Ciphertext: 49681b1e1e54fe3f 65aa832af84e0bbc 600 | { 601 | printf("**** Test Speck 128/128 ****\n"); 602 | uint8_t speck128_128_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 603 | 0x0D, 0x0E, 0x0F}; 604 | uint8_t speck128_128_plain[] = {0x20, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x20, 0x64, 605 | 0x65, 0x73, 0x63}; 606 | lw_speck_init(&ctx, 16); 607 | ret = lw_speck_setkey(&ctx, speck128_128_key, 128); 608 | if (ret != 0) { 609 | printf("lw_speck_setkey error: %d\n", ret); 610 | return ret; 611 | } 612 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck128_128_plain, ciphertext_buffer); 613 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 614 | ret = memcmp(plaintext_buffer, speck128_128_plain, sizeof(speck128_128_plain)); 615 | if (ret != 0) { 616 | printf("Test Failed!\n"); 617 | return ret; 618 | } else { 619 | printf("Test Passed!\n"); 620 | } 621 | } 622 | 623 | 624 | // Speck 192/128 Test 625 | // Key: 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 206572656874206e 6568772065626972 Ciphertext: c4ac61effcdc0d4f 6c9c8d6e2597b85b 626 | { 627 | printf("**** Test Speck 192/128 ****\n"); 628 | uint8_t speck192_128_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 629 | 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; 630 | uint8_t speck192_128_plain[] = {0x72, 0x69, 0x62, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 631 | 0x72, 0x65, 0x20}; 632 | lw_speck_init(&ctx, 16); 633 | ret = lw_speck_setkey(&ctx, speck192_128_key, 192); 634 | if (ret != 0) { 635 | printf("lw_speck_setkey error: %d\n", ret); 636 | return ret; 637 | } 638 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck192_128_plain, ciphertext_buffer); 639 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 640 | ret = memcmp(plaintext_buffer, speck192_128_plain, sizeof(speck192_128_plain)); 641 | if (ret != 0) { 642 | printf("Test Failed!\n"); 643 | return ret; 644 | } else { 645 | printf("Test Passed!\n"); 646 | } 647 | } 648 | 649 | 650 | // Speck 256/128 Test 651 | // Key: 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 74206e69206d6f6f 6d69732061207369 Ciphertext: 8d2b5579afc8a3a0 3bf72a87efe7b868 652 | { 653 | printf("**** Test Speck 256/128 ****\n"); 654 | uint8_t speck256_128_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 655 | 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 656 | 0x1A, 0x1B, 0x1C, 0x1d, 0x1e, 0x1f}; 657 | uint8_t speck256_128_plain[] = {0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6d, 0x6f, 0x6f, 0x6d, 0x20, 0x69, 658 | 0x6e, 0x20, 0x74}; 659 | lw_speck_init(&ctx, 16); 660 | ret = lw_speck_setkey(&ctx, speck256_128_key, 256); 661 | if (ret != 0) { 662 | printf("lw_speck_setkey error: %d\n", ret); 663 | return ret; 664 | } 665 | lw_speck_crypt_ecb(&ctx, SPECK_ENCRYPT, speck256_128_plain, ciphertext_buffer); 666 | lw_speck_crypt_ecb(&ctx, SPECK_DECRYPT, ciphertext_buffer, plaintext_buffer); 667 | ret = memcmp(plaintext_buffer, speck256_128_plain, sizeof(speck256_128_plain)); 668 | if (ret != 0) { 669 | printf("Test Failed!\n"); 670 | return ret; 671 | } else { 672 | printf("Test Passed!\n"); 673 | } 674 | } 675 | return 0; 676 | } 677 | 678 | 679 | void 680 | Speck_Encrypt_32(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, uint8_t *ciphertext) 681 | { 682 | 683 | const uint8_t word_size = 16; 684 | uint16_t *y_word = (uint16_t *) ciphertext; 685 | uint16_t *x_word = ((uint16_t *) ciphertext) + 1; 686 | uint16_t *round_key_ptr = (uint16_t *) key_schedule; 687 | 688 | *y_word = *(uint16_t *) plaintext; 689 | *x_word = *(((uint16_t *) plaintext) + 1); 690 | 691 | for (uint8_t i = 0; i < round_limit; i++) { 692 | *x_word = ((rotate_right(*x_word, 7)) + *y_word) ^ *(round_key_ptr + i); 693 | *y_word = (rotate_left(*y_word, 2)) ^ *x_word; 694 | } 695 | } 696 | 697 | 698 | void Speck_Encrypt_48(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 699 | uint8_t *ciphertext) 700 | { 701 | 702 | const uint8_t word_size = 24; 703 | 704 | bytes3_t *threeBytePtr = (bytes3_t *) plaintext; 705 | uint32_t y_word = (*(bitword24_t *) threeBytePtr).data; 706 | uint32_t x_word = (*(bitword24_t *) (threeBytePtr + 1)).data; 707 | threeBytePtr = (bytes3_t *) key_schedule; 708 | uint32_t round_key; 709 | 710 | for (uint8_t i = 0; i < round_limit; i++) { 711 | round_key = (*(bitword24_t *) (threeBytePtr + i)).data; 712 | x_word = (((rotate_right(x_word, 8)) + y_word) ^ round_key) & 0x00FFFFFF; 713 | y_word = ((rotate_left(y_word, 3)) ^ x_word) & 0x00FFFFFF; 714 | } 715 | // Assemble Ciphertext Output Array 716 | threeBytePtr = (bytes3_t *) ciphertext; 717 | *threeBytePtr = *(bytes3_t *) &y_word; 718 | threeBytePtr += 1; 719 | *threeBytePtr = *(bytes3_t *) &x_word; 720 | } 721 | 722 | void Speck_Encrypt_64(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 723 | uint8_t *ciphertext) 724 | { 725 | 726 | const uint8_t word_size = 32; 727 | uint32_t *y_word = (uint32_t *) ciphertext; 728 | uint32_t *x_word = ((uint32_t *) ciphertext) + 1; 729 | uint32_t *round_key_ptr = (uint32_t *) key_schedule; 730 | 731 | *y_word = *(uint32_t *) plaintext; 732 | *x_word = *(((uint32_t *) plaintext) + 1); 733 | 734 | for (uint8_t i = 0; i < round_limit; i++) { 735 | *x_word = ((rotate_right(*x_word, 8)) + *y_word) ^ *(round_key_ptr + i); 736 | *y_word = (rotate_left(*y_word, 3)) ^ *x_word; 737 | } 738 | } 739 | 740 | void Speck_Encrypt_96(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 741 | uint8_t *ciphertext) 742 | { 743 | const uint8_t word_size = 48; 744 | 745 | bytes6_t *threeBytePtr = (bytes6_t *) plaintext; 746 | uint64_t y_word = (*(bitword48_t *) threeBytePtr).data; 747 | uint64_t x_word = (*(bitword48_t *) (threeBytePtr + 1)).data; 748 | threeBytePtr = (bytes6_t *) key_schedule; 749 | uint64_t round_key; 750 | 751 | for (uint8_t i = 0; i < round_limit; i++) { 752 | round_key = (*(bitword48_t *) (threeBytePtr + i)).data; 753 | x_word = (((rotate_right(x_word, 8)) + y_word) ^ round_key) & 0x00FFFFFFFFFFFF; 754 | y_word = ((rotate_left(y_word, 3)) ^ x_word) & 0x00FFFFFFFFFFFF; 755 | } 756 | // Assemble Ciphertext Output Array 757 | threeBytePtr = (bytes6_t *) ciphertext; 758 | *threeBytePtr = *(bytes6_t *) &y_word; 759 | threeBytePtr += 1; 760 | *threeBytePtr = *(bytes6_t *) &x_word; 761 | } 762 | 763 | void Speck_Encrypt_128(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *plaintext, 764 | uint8_t *ciphertext) 765 | { 766 | 767 | const uint8_t word_size = 64; 768 | uint64_t *y_word = (uint64_t *) ciphertext; 769 | uint64_t *x_word = ((uint64_t *) ciphertext) + 1; 770 | uint64_t *round_key_ptr = (uint64_t *) key_schedule; 771 | 772 | *y_word = *(uint64_t *) plaintext; 773 | *x_word = *(((uint64_t *) plaintext) + 1); 774 | 775 | for (uint8_t i = 0; i < round_limit; i++) { 776 | *x_word = ((rotate_right(*x_word, 8)) + *y_word) ^ *(round_key_ptr + i); 777 | *y_word = (rotate_left(*y_word, 3)) ^ *x_word; 778 | } 779 | } 780 | 781 | void 782 | Speck_Decrypt_32(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, uint8_t *plaintext) 783 | { 784 | 785 | const uint8_t word_size = 16; 786 | uint16_t *y_word = (uint16_t *) plaintext; 787 | uint16_t *x_word = ((uint16_t *) plaintext) + 1; 788 | uint16_t *round_key_ptr = (uint16_t *) key_schedule; 789 | 790 | *y_word = *(uint16_t *) ciphertext; 791 | *x_word = *(((uint16_t *) ciphertext) + 1); 792 | 793 | for (int8_t i = round_limit - 1; i >= 0; i--) { 794 | *y_word = rotate_right((*y_word ^ *x_word), 2); 795 | *x_word = rotate_left((uint16_t) ((*x_word ^ *(round_key_ptr + i)) - *y_word), 7); 796 | } 797 | } 798 | 799 | void Speck_Decrypt_48(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 800 | uint8_t *plaintext) 801 | { 802 | 803 | const uint8_t word_size = 24; 804 | 805 | bytes3_t *threeBytePtr = (bytes3_t *) ciphertext; 806 | uint32_t y_word = (*(bitword24_t *) threeBytePtr).data; 807 | uint32_t x_word = (*(bitword24_t *) (threeBytePtr + 1)).data; 808 | threeBytePtr = (bytes3_t *) key_schedule; 809 | uint32_t round_key; 810 | 811 | for (int8_t i = round_limit - 1; i >= 0; i--) { 812 | round_key = (*(bitword24_t *) (threeBytePtr + i)).data; 813 | y_word = (rotate_right((y_word ^ x_word), 3)) & 0x00FFFFFF; 814 | x_word = (rotate_left(((((x_word ^ round_key)) - y_word) & 0x00FFFFFF), 8)) & 0x00FFFFFF; 815 | } 816 | 817 | // Assemble Plaintext Output Array 818 | threeBytePtr = (bytes3_t *) plaintext; 819 | *threeBytePtr = *(bytes3_t *) &y_word; 820 | threeBytePtr += 1; 821 | *threeBytePtr = *(bytes3_t *) &x_word; 822 | } 823 | 824 | void Speck_Decrypt_64(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 825 | uint8_t *plaintext) 826 | { 827 | 828 | const uint8_t word_size = 32; 829 | uint32_t *y_word = (uint32_t *) plaintext; 830 | uint32_t *x_word = ((uint32_t *) plaintext) + 1; 831 | uint32_t *round_key_ptr = (uint32_t *) key_schedule; 832 | 833 | *y_word = *(uint32_t *) ciphertext; 834 | *x_word = *(((uint32_t *) ciphertext) + 1); 835 | 836 | for (int8_t i = round_limit - 1; i >= 0; i--) { 837 | *y_word = rotate_right((*y_word ^ *x_word), 3); 838 | *x_word = rotate_left((uint32_t) ((*x_word ^ *(round_key_ptr + i)) - *y_word), 8); 839 | } 840 | } 841 | 842 | void Speck_Decrypt_96(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 843 | uint8_t *plaintext) 844 | { 845 | const uint8_t word_size = 48; 846 | 847 | bytes6_t *sixBytePtr = (bytes6_t *) ciphertext; 848 | uint64_t y_word = (*(bitword48_t *) sixBytePtr).data; 849 | uint64_t x_word = (*(bitword48_t *) (sixBytePtr + 1)).data; 850 | sixBytePtr = (bytes6_t *) key_schedule; 851 | uint64_t round_key; 852 | 853 | for (int8_t i = round_limit - 1; i >= 0; i--) { 854 | round_key = (*(bitword48_t *) (sixBytePtr + i)).data; 855 | y_word = (rotate_right((y_word ^ x_word), 3)) & 0x00FFFFFFFFFFFF; 856 | x_word = (rotate_left(((((x_word ^ round_key)) - y_word) & 0x00FFFFFFFFFFFF), 8)) & 0x00FFFFFFFFFFFF; 857 | } 858 | 859 | // Assemble Plaintext Output Array 860 | sixBytePtr = (bytes6_t *) plaintext; 861 | *sixBytePtr = *(bytes6_t *) &y_word; 862 | sixBytePtr += 1; 863 | *sixBytePtr = *(bytes6_t *) &x_word; 864 | } 865 | 866 | void Speck_Decrypt_128(const uint8_t round_limit, const uint8_t *key_schedule, const uint8_t *ciphertext, 867 | uint8_t *plaintext) 868 | { 869 | 870 | const uint8_t word_size = 64; 871 | uint64_t *y_word = (uint64_t *) plaintext; 872 | uint64_t *x_word = ((uint64_t *) plaintext) + 1; 873 | uint64_t *round_key_ptr = (uint64_t *) key_schedule; 874 | 875 | *y_word = *(uint64_t *) ciphertext; 876 | *x_word = *(((uint64_t *) ciphertext) + 1); 877 | 878 | for (int8_t i = round_limit - 1; i >= 0; i--) { 879 | *y_word = rotate_right((*y_word ^ *x_word), 3); 880 | *x_word = rotate_left((uint64_t) ((*x_word ^ *(round_key_ptr + i)) - *y_word), 8); 881 | } 882 | } 883 | 884 | -------------------------------------------------------------------------------- /src/xtea.c: -------------------------------------------------------------------------------- 1 | #include "xtea.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void lw_xtea_init(lw_xtea_context *ctx) 7 | { 8 | memset(ctx, 0, sizeof(lw_xtea_context)); 9 | } 10 | 11 | void lw_xtea_free(lw_xtea_context *ctx) 12 | { 13 | memset(ctx, 0, sizeof(lw_xtea_context)); 14 | } 15 | 16 | int lw_xtea_setkey(lw_xtea_context *ctx, const uint8_t key[16], unsigned int key_bitlen) 17 | { 18 | memcpy(ctx->key, key, 16); 19 | return 0; 20 | } 21 | 22 | int lw_xtea_crypt_ecb(lw_xtea_context *ctx, int mode, const uint8_t input[8], 23 | uint8_t output[8]) 24 | { 25 | if(mode != XTEA_ENCRYPT && mode != XTEA_DECRYPT) { 26 | return LW_ERR_XTEA_BAD_INPUT_DATA; 27 | } 28 | uint32_t i, num_rounds, v0, v1, sum, delta, k0, k1, k2, k3; 29 | num_rounds = 64; 30 | delta = 0x9E3779B9; 31 | 32 | memcpy(&v0, input + 0, 4); 33 | memcpy(&v1, input + 4, 4); 34 | 35 | if (mode == XTEA_ENCRYPT) { 36 | sum = 0; 37 | for (i = 0; i < num_rounds; i++) { 38 | v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); 39 | sum += delta; 40 | v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[sum >> 11 & 3]); 41 | } 42 | } else { /* decrypt */ 43 | sum = delta * num_rounds; 44 | for (i = 0; i < num_rounds; i++) { 45 | v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[sum >> 11 & 3]); 46 | sum -= delta; 47 | v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]); 48 | } 49 | } 50 | memcpy(output + 0, &v0, 4); 51 | memcpy(output + 4, &v1, 4); 52 | return 0; 53 | } 54 | 55 | int lw_xtea_crypt_cbc(lw_xtea_context *ctx, int mode, size_t length, uint8_t iv[8], const uint8_t *input, uint8_t *output) 56 | { 57 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 58 | unsigned char temp[8]; 59 | 60 | if (mode != XTEA_ENCRYPT && mode != XTEA_DECRYPT) { 61 | return LW_ERR_XTEA_BAD_INPUT_DATA; 62 | } 63 | 64 | /* Nothing to do if length is zero. */ 65 | if (length == 0) { 66 | return 0; 67 | } 68 | 69 | if (length % 8) { 70 | return LW_ERR_XTEA_INVALID_INPUT_LENGTH; 71 | } 72 | 73 | const unsigned char *ivp = iv; 74 | 75 | if (mode == XTEA_DECRYPT) { 76 | while (length > 0) { 77 | memcpy(temp, input, 8); 78 | ret = lw_xtea_crypt_ecb(ctx, mode, input, output); 79 | if (ret != 0) { 80 | return ret; 81 | } 82 | for (int i = 0; i < 8; i++) { 83 | output[i] = iv[i] ^ output[i]; 84 | } 85 | 86 | memcpy(iv, temp, 16); 87 | 88 | input += 8; 89 | output += 8; 90 | length -= 8; 91 | } 92 | } else { 93 | while (length > 0) { 94 | for (int i = 0; i < 8; i++) { 95 | output[i] = ivp[i] ^ input[i]; 96 | } 97 | 98 | ret = lw_xtea_crypt_ecb(ctx, mode, output, output); 99 | if (ret != 0) { 100 | return ret; 101 | } 102 | ivp = output; 103 | 104 | input += 8; 105 | output += 8; 106 | length -= 8; 107 | } 108 | memcpy(iv, ivp, 8); 109 | } 110 | ret = 0; 111 | return ret; 112 | } 113 | 114 | int lw_xtea_crypt_ctr(lw_xtea_context *ctx, size_t length, uint8_t *nc_off, uint8_t nonce_counter[8], 115 | uint8_t stream_block[8], 116 | const uint8_t *input, uint8_t *output) 117 | { 118 | int c, i; 119 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 120 | size_t n; 121 | 122 | n = *nc_off; 123 | 124 | if (n > 0b0111) { 125 | return LW_ERR_XTEA_BAD_INPUT_DATA; 126 | } 127 | 128 | while (length--) { 129 | if (n == 0) { 130 | ret = lw_xtea_crypt_ecb(ctx, XTEA_ENCRYPT, nonce_counter, stream_block); 131 | if (ret != 0) { 132 | return ret; 133 | } 134 | 135 | for (i = 8; i > 0; i--) { 136 | if (++nonce_counter[i - 1] != 0) { 137 | break; 138 | } 139 | } 140 | } 141 | c = *input++; 142 | *output++ = (unsigned char) (c ^ stream_block[n]); 143 | 144 | n = (n + 1) & 0b0111; 145 | } 146 | 147 | *nc_off = n; 148 | ret = 0; 149 | return ret; 150 | } 151 | #define print_hex(buffer, len) \ 152 | for (int i = 0; i < len; i++) { \ 153 | printf("%02x ", buffer[i]); \ 154 | } \ 155 | printf("\n"); 156 | 157 | int lw_xtea_self_test(int verbose) 158 | { 159 | int ret; 160 | const unsigned char plaintext[32] = 161 | {0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, 162 | 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4, 163 | 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, 164 | 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE}; 165 | unsigned char cipher_buffer[32] = {0}; 166 | unsigned char dec_plain_buffer[32] = {0}; 167 | const unsigned char key[8] = {0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58}; 168 | unsigned char iv[8] = {0}; 169 | unsigned char nonce_counter[8] = {0}; 170 | 171 | lw_xtea_context ctx; 172 | lw_xtea_init(&ctx); 173 | lw_xtea_setkey(&ctx, key, 128); 174 | lw_xtea_crypt_ecb(&ctx, XTEA_ENCRYPT, plaintext, cipher_buffer); 175 | lw_xtea_crypt_ecb(&ctx, XTEA_DECRYPT, cipher_buffer, dec_plain_buffer); 176 | lw_xtea_crypt_ecb(&ctx, XTEA_ENCRYPT, plaintext + 8, cipher_buffer + 8); 177 | lw_xtea_crypt_ecb(&ctx, XTEA_DECRYPT, cipher_buffer + 8, dec_plain_buffer + 8); 178 | lw_xtea_crypt_ecb(&ctx, XTEA_ENCRYPT, plaintext + 16, cipher_buffer + 16); 179 | lw_xtea_crypt_ecb(&ctx, XTEA_DECRYPT, cipher_buffer + 16, dec_plain_buffer + 16); 180 | lw_xtea_crypt_ecb(&ctx, XTEA_ENCRYPT, plaintext + 24, cipher_buffer + 24); 181 | lw_xtea_crypt_ecb(&ctx, XTEA_DECRYPT, cipher_buffer + 24, dec_plain_buffer + 24); 182 | ret = memcmp(plaintext, dec_plain_buffer, 32); 183 | if (ret != 0) { 184 | printf("xtea self test ecb failed\n"); 185 | return ret; 186 | } else { 187 | printf("xtea self test ecb passed\n"); 188 | } 189 | 190 | lw_xtea_init(&ctx); 191 | lw_xtea_setkey(&ctx, key, 128); 192 | lw_xtea_crypt_cbc(&ctx, XTEA_ENCRYPT, 32, iv, plaintext, cipher_buffer); 193 | memset(iv, 0, 8); 194 | lw_xtea_crypt_cbc(&ctx, XTEA_DECRYPT, 32, iv, cipher_buffer, dec_plain_buffer); 195 | ret = memcmp(plaintext, dec_plain_buffer, 32); 196 | if (ret != 0) { 197 | printf("xtea self test cbc failed\n"); 198 | return ret; 199 | } else { 200 | printf("xtea self test cbc passed\n"); 201 | } 202 | 203 | lw_xtea_init(&ctx); 204 | lw_xtea_setkey(&ctx, key, 128); 205 | uint8_t nc_off = 0; 206 | unsigned char stream_block[8] = {0}; 207 | unsigned char nonce_counter_for_enc[8] = {0}; 208 | memcpy(nonce_counter_for_enc, nonce_counter, 8); 209 | lw_xtea_crypt_ctr(&ctx, 32, &nc_off, nonce_counter_for_enc, stream_block, plaintext, cipher_buffer); 210 | nc_off = 0; 211 | lw_xtea_crypt_ctr(&ctx, 32, &nc_off, nonce_counter, stream_block, cipher_buffer, dec_plain_buffer); 212 | ret = memcmp(plaintext, dec_plain_buffer, 32); 213 | if (ret != 0) { 214 | printf("xtea self test ctr failed\n"); 215 | return ret; 216 | } else { 217 | printf("xtea self test ctr passed\n"); 218 | } 219 | 220 | return ret; 221 | } -------------------------------------------------------------------------------- /src/xxtea.c: -------------------------------------------------------------------------------- 1 | #include "xxtea.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void lw_xxtea_init(lw_xxtea_context *ctx) 7 | { 8 | memset(ctx, 0, sizeof(lw_xxtea_context)); 9 | } 10 | 11 | void lw_xxtea_free(lw_xxtea_context *ctx) 12 | { 13 | memset(ctx, 0, sizeof(lw_xxtea_context)); 14 | } 15 | 16 | int lw_xxtea_setkey(lw_xxtea_context *ctx, const uint8_t key[16], unsigned int key_bitlen) 17 | { 18 | memcpy(ctx->key, key, 16); 19 | return 0; 20 | } 21 | 22 | int lw_xxtea_crypt_ecb(lw_xxtea_context *ctx, int mode, const uint8_t input[8], uint8_t output[8]) 23 | { 24 | #define DELTA 0x9e3779b9 25 | #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z))) 26 | uint32_t v[2]; 27 | memcpy(v, input, 8); 28 | int n = 2; 29 | uint32_t *key = ctx->key; 30 | // void btea(uint32_t *v, int n, uint32_t const key[4]) 31 | uint32_t y, z, sum; 32 | unsigned p, rounds, e; 33 | if (mode == XXTEA_ENCRYPT) { /* Coding Part */ 34 | rounds = 6 + 52 / n; 35 | sum = 0; 36 | z = v[n - 1]; 37 | do { 38 | sum += DELTA; 39 | e = (sum >> 2) & 3; 40 | for (p = 0; p < n - 1; p++) { 41 | y = v[p + 1]; 42 | z = v[p] += MX; 43 | } 44 | y = v[0]; 45 | z = v[n - 1] += MX; 46 | } while (--rounds); 47 | } else if (mode == XXTEA_DECRYPT) { /* Decoding Part */ 48 | // n = -n; 49 | rounds = 6 + 52 / n; 50 | sum = rounds * DELTA; 51 | y = v[0]; 52 | do { 53 | e = (sum >> 2) & 3; 54 | for (p = n - 1; p > 0; p--) { 55 | z = v[p - 1]; 56 | y = v[p] -= MX; 57 | } 58 | z = v[n - 1]; 59 | y = v[0] -= MX; 60 | sum -= DELTA; 61 | } while (--rounds); 62 | } 63 | memcpy(output, v, 8); 64 | return 0; 65 | } 66 | 67 | int lw_xxtea_crypt_cbc(lw_xxtea_context *ctx, int mode, size_t length, uint8_t iv[8], const uint8_t *input, uint8_t *output) 68 | { 69 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 70 | unsigned char temp[8]; 71 | if (mode != XXTEA_ENCRYPT && mode != XXTEA_DECRYPT) { 72 | return LW_ERR_XXTEA_BAD_INPUT_DATA; 73 | } 74 | /* Nothing to do if length is zero. */ 75 | if (length == 0) { 76 | return 0; 77 | } 78 | if (length % 8) { 79 | return LW_ERR_XXTEA_INVALID_INPUT_LENGTH; 80 | } 81 | const unsigned char *ivp = iv; 82 | if (mode == XXTEA_DECRYPT) { 83 | while (length > 0) { 84 | memcpy(temp, input, 8); 85 | ret = lw_xxtea_crypt_ecb(ctx, mode, input, output); 86 | if (ret != 0) { 87 | return ret; 88 | } 89 | for (int i = 0; i < 8; i++) { 90 | output[i] = iv[i] ^ output[i]; 91 | } 92 | memcpy(iv, temp, 8); 93 | input += 8; 94 | output += 8; 95 | length -= 8; 96 | } 97 | } else { 98 | while (length > 0) { 99 | for (int i = 0; i < 8; i++) { 100 | output[i] = ivp[i] ^ input[i]; 101 | } 102 | ret = lw_xxtea_crypt_ecb(ctx, mode, output, output); 103 | if (ret != 0) { 104 | return ret; 105 | } 106 | ivp = output; 107 | input += 8; 108 | output += 8; 109 | length -= 8; 110 | } 111 | memcpy(iv, ivp, 8); 112 | } 113 | ret = 0; 114 | return ret; 115 | } 116 | 117 | int lw_xxtea_crypt_ctr(lw_xxtea_context *ctx, size_t length, uint8_t *nc_off, uint8_t nonce_counter[8], 118 | uint8_t stream_block[8], 119 | const uint8_t *input, uint8_t *output) 120 | { 121 | int c, i; 122 | int ret = LW_ERR_ERROR_CORRUPTION_DETECTED; 123 | size_t n; 124 | n = *nc_off; 125 | if (n > 0b0111) { 126 | return LW_ERR_XXTEA_BAD_INPUT_DATA; 127 | } 128 | while (length--) { 129 | if (n == 0) { 130 | ret = lw_xxtea_crypt_ecb(ctx, XXTEA_ENCRYPT, nonce_counter, stream_block); 131 | if (ret != 0) { 132 | return ret; 133 | } 134 | 135 | for (i = 8; i > 0; i--) { 136 | if (++nonce_counter[i - 1] != 0) { 137 | break; 138 | } 139 | } 140 | } 141 | c = *input++; 142 | *output++ = (unsigned char) (c ^ stream_block[n]); 143 | n = (n + 1) & 0b0111; 144 | } 145 | *nc_off = n; 146 | ret = 0; 147 | return ret; 148 | } 149 | 150 | #define print_hex(buffer, len) \ 151 | for (int i = 0; i < len; i++) { \ 152 | printf("%02x ", buffer[i]); \ 153 | } \ 154 | printf("\n"); 155 | 156 | 157 | int lw_xxtea_self_test(int verbose) 158 | { 159 | int ret; 160 | const unsigned char plaintext[32] = 161 | {0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, 162 | 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4, 163 | 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, 164 | 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE}; 165 | unsigned char cipher_buffer[32] = {0}; 166 | unsigned char dec_plain_buffer[32] = {0}; 167 | const unsigned char key[8] = {0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58}; 168 | unsigned char iv[8] = {0}; 169 | unsigned char nonce_counter[8] = {0}; 170 | lw_xxtea_context ctx; 171 | lw_xxtea_init(&ctx); 172 | lw_xxtea_setkey(&ctx, key, 128); 173 | lw_xxtea_crypt_ecb(&ctx, XXTEA_ENCRYPT, plaintext, cipher_buffer); 174 | lw_xxtea_crypt_ecb(&ctx, XXTEA_DECRYPT, cipher_buffer, dec_plain_buffer); 175 | lw_xxtea_crypt_ecb(&ctx, XXTEA_ENCRYPT, plaintext + 8, cipher_buffer + 8); 176 | lw_xxtea_crypt_ecb(&ctx, XXTEA_DECRYPT, cipher_buffer + 8, dec_plain_buffer + 8); 177 | lw_xxtea_crypt_ecb(&ctx, XXTEA_ENCRYPT, plaintext + 16, cipher_buffer + 16); 178 | lw_xxtea_crypt_ecb(&ctx, XXTEA_DECRYPT, cipher_buffer + 16, dec_plain_buffer + 16); 179 | lw_xxtea_crypt_ecb(&ctx, XXTEA_ENCRYPT, plaintext + 24, cipher_buffer + 24); 180 | lw_xxtea_crypt_ecb(&ctx, XXTEA_DECRYPT, cipher_buffer + 24, dec_plain_buffer + 24); 181 | if (verbose) { 182 | printf("plaintext:\n"); 183 | print_hex(plaintext, 32); 184 | printf("cipher_buffer:\n"); 185 | print_hex(cipher_buffer, 32); 186 | printf("dec_plain_buffer:\n"); 187 | print_hex(dec_plain_buffer, 32); 188 | } 189 | ret = memcmp(plaintext, dec_plain_buffer, 32); 190 | memset(cipher_buffer, 0, 32); 191 | memset(dec_plain_buffer, 0, 32); 192 | if (ret != 0) { 193 | printf("xxtea self test ecb failed\n"); 194 | return ret; 195 | } else { 196 | printf("xxtea self test ecb passed\n"); 197 | } 198 | lw_xxtea_init(&ctx); 199 | lw_xxtea_setkey(&ctx, key, 128); 200 | lw_xxtea_crypt_cbc(&ctx, XXTEA_ENCRYPT, 32, iv, plaintext, cipher_buffer); 201 | memset(iv, 0, 8); 202 | lw_xxtea_crypt_cbc(&ctx, XXTEA_DECRYPT, 32, iv, cipher_buffer, dec_plain_buffer); 203 | if (verbose) { 204 | printf("plaintext:\n"); 205 | print_hex(plaintext, 32); 206 | printf("cipher_buffer:\n"); 207 | print_hex(cipher_buffer, 32); 208 | printf("dec_plain_buffer:\n"); 209 | print_hex(dec_plain_buffer, 32); 210 | } 211 | ret = memcmp(plaintext, dec_plain_buffer, 32); 212 | memset(cipher_buffer, 0, 32); 213 | memset(dec_plain_buffer, 0, 32); 214 | if (ret != 0) { 215 | printf("xxtea self test cbc failed\n"); 216 | return ret; 217 | } else { 218 | printf("xxtea self test cbc passed\n"); 219 | } 220 | lw_xxtea_init(&ctx); 221 | lw_xxtea_setkey(&ctx, key, 128); 222 | uint8_t nc_off = 0; 223 | unsigned char stream_block[8] = {0}; 224 | unsigned char nonce_counter_for_enc[8] = {0}; 225 | memcpy(nonce_counter_for_enc, nonce_counter, 8); 226 | lw_xxtea_crypt_ctr(&ctx, 32, &nc_off, nonce_counter_for_enc, stream_block, plaintext, cipher_buffer); 227 | nc_off = 0; 228 | lw_xxtea_crypt_ctr(&ctx, 32, &nc_off, nonce_counter, stream_block, cipher_buffer, dec_plain_buffer); 229 | if (verbose) { 230 | printf("plaintext:\n"); 231 | print_hex(plaintext, 32); 232 | printf("cipher_buffer:\n"); 233 | print_hex(cipher_buffer, 32); 234 | printf("dec_plain_buffer:\n"); 235 | print_hex(dec_plain_buffer, 32); 236 | } 237 | ret = memcmp(plaintext, dec_plain_buffer, 32); 238 | memset(cipher_buffer, 0, 32); 239 | memset(dec_plain_buffer, 0, 32); 240 | if (ret != 0) { 241 | printf("xxtea self test ctr failed\n"); 242 | return ret; 243 | } else { 244 | printf("xxtea self test ctr passed\n"); 245 | } 246 | return ret; 247 | } 248 | --------------------------------------------------------------------------------