Merge pull request #1004 from cheloftus/dev
Added crypto.fhash function for hashing files
This commit is contained in:
commit
68919dea65
|
@ -122,6 +122,39 @@ int ICACHE_FLASH_ATTR crypto_hash (const digest_mech_info_t *mi,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ICACHE_FLASH_ATTR crypto_fhash (const digest_mech_info_t *mi,
|
||||||
|
read_fn read, int readarg,
|
||||||
|
uint8_t *digest)
|
||||||
|
{
|
||||||
|
if (!mi)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
// Initialise
|
||||||
|
void *ctx = (void *)os_malloc (mi->ctx_size);
|
||||||
|
if (!ctx)
|
||||||
|
return ENOMEM;
|
||||||
|
mi->create (ctx);
|
||||||
|
|
||||||
|
// Hash bytes from file in blocks
|
||||||
|
uint8_t* buffer = (uint8_t*)os_malloc (mi->block_size);
|
||||||
|
if (!buffer)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
int read_len = 0;
|
||||||
|
do {
|
||||||
|
read_len = read(readarg, buffer, mi->block_size);
|
||||||
|
mi->update (ctx, buffer, read_len);
|
||||||
|
} while (read_len == mi->block_size);
|
||||||
|
|
||||||
|
// Finish up
|
||||||
|
mi->finalize (digest, ctx);
|
||||||
|
|
||||||
|
os_free (buffer);
|
||||||
|
os_free (ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int ICACHE_FLASH_ATTR crypto_hmac (const digest_mech_info_t *mi,
|
int ICACHE_FLASH_ATTR crypto_hmac (const digest_mech_info_t *mi,
|
||||||
const char *data, size_t data_len,
|
const char *data, size_t data_len,
|
||||||
const char *key, size_t key_len,
|
const char *key, size_t key_len,
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
typedef void (*create_ctx_fn)(void *ctx);
|
typedef void (*create_ctx_fn)(void *ctx);
|
||||||
typedef void (*update_ctx_fn)(void *ctx, const uint8_t *msg, int len);
|
typedef void (*update_ctx_fn)(void *ctx, const uint8_t *msg, int len);
|
||||||
typedef void (*finalize_ctx_fn)(uint8_t *digest, void *ctx);
|
typedef void (*finalize_ctx_fn)(uint8_t *digest, void *ctx);
|
||||||
|
typedef size_t ( *read_fn )(int fd, void *ptr, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of a message digest mechanism.
|
* Description of a message digest mechanism.
|
||||||
|
@ -53,6 +54,16 @@ const digest_mech_info_t *crypto_digest_mech (const char *mech);
|
||||||
*/
|
*/
|
||||||
int crypto_hash (const digest_mech_info_t *mi, const char *data, size_t data_len, uint8_t *digest);
|
int crypto_hash (const digest_mech_info_t *mi, const char *data, size_t data_len, uint8_t *digest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper function for performing a one-in-all hashing operation of a file.
|
||||||
|
* @param mi A mech from @c crypto_digest_mech(). A null pointer @c mi
|
||||||
|
* is harmless, but will of course result in an error return.
|
||||||
|
* @param read Pointer to the read function (e.g. fs_read)
|
||||||
|
* @param readarg Argument to pass to the read function (e.g. file descriptor)
|
||||||
|
* @param digest Output buffer, must be at least @c mi->digest_size in size.
|
||||||
|
* @return 0 on success, non-zero on error.
|
||||||
|
*/
|
||||||
|
int crypto_fhash (const digest_mech_info_t *mi, read_fn read, int readarg, uint8_t *digest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a HMAC signature.
|
* Generate a HMAC signature.
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
// Module for cryptography
|
// Module for cryptography
|
||||||
|
|
||||||
|
#include <c_errno.h>
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "c_types.h"
|
#include "c_types.h"
|
||||||
#include "c_stdlib.h"
|
#include "c_stdlib.h"
|
||||||
|
#include "flash_fs.h"
|
||||||
#include "../crypto/digests.h"
|
#include "../crypto/digests.h"
|
||||||
#include "../crypto/mech.h"
|
#include "../crypto/mech.h"
|
||||||
|
|
||||||
|
@ -106,6 +108,7 @@ static int crypto_mask( lua_State* L )
|
||||||
|
|
||||||
static inline int bad_mech (lua_State *L) { return luaL_error (L, "unknown hash mech"); }
|
static inline int bad_mech (lua_State *L) { return luaL_error (L, "unknown hash mech"); }
|
||||||
static inline int bad_mem (lua_State *L) { return luaL_error (L, "insufficient memory"); }
|
static inline int bad_mem (lua_State *L) { return luaL_error (L, "insufficient memory"); }
|
||||||
|
static inline int bad_file (lua_State *L) { return luaL_error (L, "file does not exist"); }
|
||||||
|
|
||||||
|
|
||||||
/* rawdigest = crypto.hash("MD5", str)
|
/* rawdigest = crypto.hash("MD5", str)
|
||||||
|
@ -128,6 +131,40 @@ static int crypto_lhash (lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* rawdigest = crypto.hash("MD5", filename)
|
||||||
|
* strdigest = crypto.toHex(rawdigest)
|
||||||
|
*/
|
||||||
|
static int crypto_flhash (lua_State *L)
|
||||||
|
{
|
||||||
|
const digest_mech_info_t *mi = crypto_digest_mech (luaL_checkstring (L, 1));
|
||||||
|
if (!mi)
|
||||||
|
return bad_mech (L);
|
||||||
|
const char *filename = luaL_checkstring (L, 2);
|
||||||
|
|
||||||
|
// Open the file
|
||||||
|
int file_fd = fs_open (filename, FS_RDONLY);
|
||||||
|
if(file_fd < FS_OPEN_OK) {
|
||||||
|
return bad_file(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute hash
|
||||||
|
uint8_t digest[mi->digest_size];
|
||||||
|
int returncode = crypto_fhash (mi, &fs_read, file_fd, digest);
|
||||||
|
|
||||||
|
// Finish up
|
||||||
|
fs_close(file_fd);
|
||||||
|
|
||||||
|
if (returncode == ENOMEM)
|
||||||
|
return bad_mem (L);
|
||||||
|
else if (returncode == EINVAL)
|
||||||
|
return bad_mech(L);
|
||||||
|
else
|
||||||
|
lua_pushlstring (L, digest, sizeof (digest));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* rawsignature = crypto.hmac("SHA1", str, key)
|
/* rawsignature = crypto.hmac("SHA1", str, key)
|
||||||
* strsignature = crypto.toHex(rawsignature)
|
* strsignature = crypto.toHex(rawsignature)
|
||||||
*/
|
*/
|
||||||
|
@ -220,6 +257,7 @@ static const LUA_REG_TYPE crypto_map[] = {
|
||||||
{ LSTRKEY( "toHex" ), LFUNCVAL( crypto_hex_encode ) },
|
{ LSTRKEY( "toHex" ), LFUNCVAL( crypto_hex_encode ) },
|
||||||
{ LSTRKEY( "mask" ), LFUNCVAL( crypto_mask ) },
|
{ LSTRKEY( "mask" ), LFUNCVAL( crypto_mask ) },
|
||||||
{ LSTRKEY( "hash" ), LFUNCVAL( crypto_lhash ) },
|
{ LSTRKEY( "hash" ), LFUNCVAL( crypto_lhash ) },
|
||||||
|
{ LSTRKEY( "fhash" ), LFUNCVAL( crypto_flhash ) },
|
||||||
{ LSTRKEY( "hmac" ), LFUNCVAL( crypto_lhmac ) },
|
{ LSTRKEY( "hmac" ), LFUNCVAL( crypto_lhmac ) },
|
||||||
{ LSTRKEY( "encrypt" ), LFUNCVAL( lcrypto_encrypt ) },
|
{ LSTRKEY( "encrypt" ), LFUNCVAL( lcrypto_encrypt ) },
|
||||||
{ LSTRKEY( "decrypt" ), LFUNCVAL( lcrypto_decrypt ) },
|
{ LSTRKEY( "decrypt" ), LFUNCVAL( lcrypto_decrypt ) },
|
||||||
|
|
|
@ -61,6 +61,32 @@ print(crypto.decrypt("AES-ECB", key, cipher))
|
||||||
- [`crypto.encrypt()`](#cryptoencrypt)
|
- [`crypto.encrypt()`](#cryptoencrypt)
|
||||||
|
|
||||||
|
|
||||||
|
## crypto.fhash()
|
||||||
|
|
||||||
|
Compute a cryptographic hash of a a file.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`hash = crypto.fhash(algo, filename)`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
- `algo` the hash algorithm to use, case insensitive string
|
||||||
|
- `filename` the path to the file to hash
|
||||||
|
|
||||||
|
Supported hash algorithms are:
|
||||||
|
|
||||||
|
- MD2 (not available by default, has to be explicitly enabled in `app/include/user_config.h`)
|
||||||
|
- MD5
|
||||||
|
- SHA1
|
||||||
|
- SHA256, SHA384, SHA512 (unless disabled in `app/include/user_config.h`)
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
A binary string containing the message digest. To obtain the textual version (ASCII hex characters), please use [`crypto.toHex()`](#cryptotohex ).
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
```lua
|
||||||
|
print(crypto.toHex(crypto.fhash("sha1","myfile.lua")))
|
||||||
|
```
|
||||||
|
|
||||||
## crypto.hash()
|
## crypto.hash()
|
||||||
|
|
||||||
Compute a cryptographic hash of a Lua string.
|
Compute a cryptographic hash of a Lua string.
|
||||||
|
|
Loading…
Reference in New Issue