mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
add padding mode for DES, see #1179
This commit is contained in:
@@ -9,6 +9,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define PADDING_MODE_ISO7816_4 0
|
||||||
|
#define PADDING_MODE_PKCS7 1
|
||||||
|
#define PADDING_MODE_COUNT 2
|
||||||
|
|
||||||
#define SMALL_CHUNK 256
|
#define SMALL_CHUNK 256
|
||||||
|
|
||||||
/* the eight DES S-boxes */
|
/* the eight DES S-boxes */
|
||||||
@@ -353,6 +357,97 @@ lrandomkey(lua_State *L) {
|
|||||||
return 1;
|
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
|
static void
|
||||||
des_key(lua_State *L, uint32_t SK[32]) {
|
des_key(lua_State *L, uint32_t SK[32]) {
|
||||||
size_t keysz = 0;
|
size_t keysz = 0;
|
||||||
@@ -371,6 +466,7 @@ ldesencode(lua_State *L) {
|
|||||||
size_t textsz = 0;
|
size_t textsz = 0;
|
||||||
const uint8_t * text = (const uint8_t *)luaL_checklstring(L, 2, &textsz);
|
const uint8_t * text = (const uint8_t *)luaL_checklstring(L, 2, &textsz);
|
||||||
size_t chunksz = (textsz + 8) & ~7;
|
size_t chunksz = (textsz + 8) & ~7;
|
||||||
|
int padding_mode = luaL_optinteger(L, 3, PADDING_MODE_ISO7816_4);
|
||||||
uint8_t tmp[SMALL_CHUNK];
|
uint8_t tmp[SMALL_CHUNK];
|
||||||
uint8_t *buffer = tmp;
|
uint8_t *buffer = tmp;
|
||||||
if (chunksz > SMALL_CHUNK) {
|
if (chunksz > SMALL_CHUNK) {
|
||||||
@@ -380,18 +476,8 @@ ldesencode(lua_State *L) {
|
|||||||
for (i=0;i<(int)textsz-7;i+=8) {
|
for (i=0;i<(int)textsz-7;i+=8) {
|
||||||
des_crypt(SK, text+i, buffer+i);
|
des_crypt(SK, text+i, buffer+i);
|
||||||
}
|
}
|
||||||
int bytes = textsz - i;
|
|
||||||
uint8_t tail[8];
|
uint8_t tail[8];
|
||||||
int j;
|
add_padding(L, tail, text+i, textsz - i, padding_mode);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
des_crypt(SK, tail, buffer+i);
|
des_crypt(SK, tail, buffer+i);
|
||||||
lua_pushlstring(L, (const char *)buffer, chunksz);
|
lua_pushlstring(L, (const char *)buffer, chunksz);
|
||||||
|
|
||||||
@@ -413,6 +499,7 @@ ldesdecode(lua_State *L) {
|
|||||||
if ((textsz & 7) || textsz == 0) {
|
if ((textsz & 7) || textsz == 0) {
|
||||||
return luaL_error(L, "Invalid des crypt text length %d", (int)textsz);
|
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 tmp[SMALL_CHUNK];
|
||||||
uint8_t *buffer = tmp;
|
uint8_t *buffer = tmp;
|
||||||
if (textsz > SMALL_CHUNK) {
|
if (textsz > SMALL_CHUNK) {
|
||||||
@@ -421,17 +508,8 @@ ldesdecode(lua_State *L) {
|
|||||||
for (i=0;i<textsz;i+=8) {
|
for (i=0;i<textsz;i+=8) {
|
||||||
des_crypt(SK, text+i, buffer+i);
|
des_crypt(SK, text+i, buffer+i);
|
||||||
}
|
}
|
||||||
int padding = 1;
|
int padding = remove_padding(L, buffer + textsz - 1, padding_mode);
|
||||||
for (i=textsz-1;i>=textsz-8;i--) {
|
if (padding <= 0 || padding > 8) {
|
||||||
if (buffer[i] == 0) {
|
|
||||||
padding++;
|
|
||||||
} else if (buffer[i] == 0x80) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
return luaL_error(L, "Invalid des crypt text");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (padding > 8) {
|
|
||||||
return luaL_error(L, "Invalid des crypt text");
|
return luaL_error(L, "Invalid des crypt text");
|
||||||
}
|
}
|
||||||
lua_pushlstring(L, (const char *)buffer, textsz - padding);
|
lua_pushlstring(L, (const char *)buffer, textsz - padding);
|
||||||
@@ -954,6 +1032,7 @@ lxor_str(lua_State *L) {
|
|||||||
int lsha1(lua_State *L);
|
int lsha1(lua_State *L);
|
||||||
int lhmac_sha1(lua_State *L);
|
int lhmac_sha1(lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
LUAMOD_API int
|
LUAMOD_API int
|
||||||
luaopen_skynet_crypt(lua_State *L) {
|
luaopen_skynet_crypt(lua_State *L) {
|
||||||
luaL_checkversion(L);
|
luaL_checkversion(L);
|
||||||
@@ -980,9 +1059,14 @@ luaopen_skynet_crypt(lua_State *L) {
|
|||||||
{ "hmac_sha1", lhmac_sha1 },
|
{ "hmac_sha1", lhmac_sha1 },
|
||||||
{ "hmac_hash", lhmac_hash },
|
{ "hmac_hash", lhmac_hash },
|
||||||
{ "xor_str", lxor_str },
|
{ "xor_str", lxor_str },
|
||||||
|
{ "padding", NULL },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
luaL_newlib(L,l);
|
luaL_newlib(L,l);
|
||||||
|
|
||||||
|
padding_mode_table(L);
|
||||||
|
lua_setfield(L, -2, "padding");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
24
test/testcrypt.lua
Normal file
24
test/testcrypt.lua
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local crypt = require "skynet.crypt"
|
||||||
|
|
||||||
|
local text = "hello world"
|
||||||
|
local key = "12345678"
|
||||||
|
|
||||||
|
local function desencode(key, text, padding)
|
||||||
|
local c = crypt.desencode(key, text, crypt.padding[padding or "iso7816_4"])
|
||||||
|
return crypt.base64encode(c)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function desdecode(key, text, padding)
|
||||||
|
text = crypt.base64decode(text)
|
||||||
|
return crypt.desdecode(key, text, crypt.padding[padding or "iso7816_4"])
|
||||||
|
end
|
||||||
|
|
||||||
|
local etext = desencode(key, text)
|
||||||
|
assert( etext == "KNugLrX23UcGtcVlk9y+LA==")
|
||||||
|
assert(desdecode(key, etext) == text)
|
||||||
|
|
||||||
|
local etext = desencode(key, text, "pkcs7")
|
||||||
|
assert(desdecode(key, etext, "pkcs7") == text)
|
||||||
|
|
||||||
|
skynet.start(skynet.exit)
|
||||||
Reference in New Issue
Block a user