add padding mode for DES, see #1179

This commit is contained in:
Cloud Wu
2020-04-23 11:45:35 +08:00
parent 22f25bad55
commit 2389772c73
2 changed files with 130 additions and 22 deletions

View File

@@ -9,6 +9,10 @@
#include <stdlib.h>
#include <unistd.h>
#define PADDING_MODE_ISO7816_4 0
#define PADDING_MODE_PKCS7 1
#define PADDING_MODE_COUNT 2
#define SMALL_CHUNK 256
/* the eight DES S-boxes */
@@ -353,6 +357,97 @@ lrandomkey(lua_State *L) {
return 1;
}
static void
padding_mode_table(lua_State *L) {
// see macros PADDING_MODE_ISO7816_4, etc.
const char * mode[] = {
"iso7816_4",
"pkcs7",
};
int n = sizeof(mode) / sizeof(mode[0]);
int i;
lua_createtable(L,0,n);
for (i=0;i<n;i++) {
lua_pushinteger(L, i);
lua_setfield(L, -2, mode[i]);
}
}
typedef void (*padding_add)(uint8_t buf[8], int offset);
typedef int (*padding_remove)(const uint8_t *last);
static void
padding_add_iso7816_4(uint8_t buf[8], int offset) {
buf[offset] = 0x80;
memset(buf+offset+1, 0, 7-offset);
}
static int
padding_remove_iso7816_4(const uint8_t *last) {
int padding = 1;
int i;
for (i=0;i<8;i++,last--) {
if (*last == 0) {
padding++;
} else if (*last == 0x80) {
return padding;
} else {
break;
}
}
// invalid
return 0;
}
static void
padding_add_pkcs7(uint8_t buf[8], int offset) {
uint8_t x = 8-offset;
memset(buf+offset, x, 8-offset);
}
static int
padding_remove_pkcs7(const uint8_t *last) {
int padding = *last;
int i;
for (i=1;i<padding;i++) {
--last;
if (*last != padding)
return 0; // invalid
}
return padding;
}
static padding_add padding_add_func[] = {
padding_add_iso7816_4,
padding_add_pkcs7,
};
static padding_remove padding_remove_func[] = {
padding_remove_iso7816_4,
padding_remove_pkcs7,
};
static inline void
check_padding_mode(lua_State *L, int mode) {
if (mode < 0 || mode >= PADDING_MODE_COUNT)
luaL_error(L, "Invalid padding mode %d", mode);
}
static void
add_padding(lua_State *L, uint8_t buf[8], const uint8_t *src, int offset, int mode) {
check_padding_mode(L, mode);
if (offset >= 8)
luaL_error(L, "Invalid padding");
memcpy(buf, src, offset);
padding_add_func[mode](buf, offset);
}
static int
remove_padding(lua_State *L, const uint8_t *last, int mode) {
check_padding_mode(L, mode);
return padding_remove_func[mode](last);
}
static void
des_key(lua_State *L, uint32_t SK[32]) {
size_t keysz = 0;
@@ -371,6 +466,7 @@ ldesencode(lua_State *L) {
size_t textsz = 0;
const uint8_t * text = (const uint8_t *)luaL_checklstring(L, 2, &textsz);
size_t chunksz = (textsz + 8) & ~7;
int padding_mode = luaL_optinteger(L, 3, PADDING_MODE_ISO7816_4);
uint8_t tmp[SMALL_CHUNK];
uint8_t *buffer = tmp;
if (chunksz > SMALL_CHUNK) {
@@ -380,18 +476,8 @@ ldesencode(lua_State *L) {
for (i=0;i<(int)textsz-7;i+=8) {
des_crypt(SK, text+i, buffer+i);
}
int bytes = textsz - i;
uint8_t tail[8];
int j;
for (j=0;j<8;j++) {
if (j < bytes) {
tail[j] = text[i+j];
} else if (j==bytes) {
tail[j] = 0x80;
} else {
tail[j] = 0;
}
}
add_padding(L, tail, text+i, textsz - i, padding_mode);
des_crypt(SK, tail, buffer+i);
lua_pushlstring(L, (const char *)buffer, chunksz);
@@ -413,6 +499,7 @@ ldesdecode(lua_State *L) {
if ((textsz & 7) || textsz == 0) {
return luaL_error(L, "Invalid des crypt text length %d", (int)textsz);
}
int padding_mode = luaL_optinteger(L, 3, PADDING_MODE_ISO7816_4);
uint8_t tmp[SMALL_CHUNK];
uint8_t *buffer = tmp;
if (textsz > SMALL_CHUNK) {
@@ -421,17 +508,8 @@ ldesdecode(lua_State *L) {
for (i=0;i<textsz;i+=8) {
des_crypt(SK, text+i, buffer+i);
}
int padding = 1;
for (i=textsz-1;i>=textsz-8;i--) {
if (buffer[i] == 0) {
padding++;
} else if (buffer[i] == 0x80) {
break;
} else {
return luaL_error(L, "Invalid des crypt text");
}
}
if (padding > 8) {
int padding = remove_padding(L, buffer + textsz - 1, padding_mode);
if (padding <= 0 || padding > 8) {
return luaL_error(L, "Invalid des crypt text");
}
lua_pushlstring(L, (const char *)buffer, textsz - padding);
@@ -954,6 +1032,7 @@ lxor_str(lua_State *L) {
int lsha1(lua_State *L);
int lhmac_sha1(lua_State *L);
LUAMOD_API int
luaopen_skynet_crypt(lua_State *L) {
luaL_checkversion(L);
@@ -980,9 +1059,14 @@ luaopen_skynet_crypt(lua_State *L) {
{ "hmac_sha1", lhmac_sha1 },
{ "hmac_hash", lhmac_hash },
{ "xor_str", lxor_str },
{ "padding", NULL },
{ NULL, NULL },
};
luaL_newlib(L,l);
padding_mode_table(L);
lua_setfield(L, -2, "padding");
return 1;
}