├── Makefile ├── README ├── config ├── doc └── us │ ├── examples.html │ ├── index.html │ ├── license.html │ ├── luacrypto-128.png │ └── manual.html ├── htdocs └── index.html ├── src ├── lcrypto.c └── lcrypto.h └── tests ├── message ├── rand.lua └── test.lua /Makefile: -------------------------------------------------------------------------------- 1 | T= lcrypto 2 | V= 0.3.0 3 | CONFIG= ./config 4 | 5 | include $(CONFIG) 6 | 7 | ifeq "$(LUA_VERSION_NUM)" "500" 8 | COMPAT_O= $(COMPAT_DIR)/compat-5.1.o 9 | endif 10 | OBJS= src/$T.o $(COMPAT_O) 11 | SRCS= src/$T.h src/$T.c 12 | 13 | lib: src/$(LIBNAME) 14 | 15 | src/$(LIBNAME): $(OBJS) 16 | export MACOSX_DEPLOYMENT_TARGET="10.3"; $(CC) $(CFLAGS) $(LIB_OPTION) -o src/$(LIBNAME) $(OBJS) $(LUACRYPTO_LIBS) 17 | 18 | $(COMPAT_DIR)/compat-5.1.o: $(COMPAT_DIR)/compat-5.1.c 19 | $(CC) -c $(CFLAGS) -o $@ $(COMPAT_DIR)/compat-5.1.c 20 | 21 | install: src/$(LIBNAME) 22 | mkdir -p $(LUA_LIBDIR) 23 | cp src/$(LIBNAME) $(LUA_LIBDIR) 24 | cd $(LUA_LIBDIR); ln -f -s $(LIBNAME) $T.so 25 | 26 | clean: 27 | rm -f src/$(LIBNAME) $(OBJS) $(COMPAT_O) 28 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | LuaCrypto provides a Lua frontend to the OpenSSL cryptographic library. 2 | The OpenSSL features that are currently exposed are digests (MD5, SHA-1, 3 | HMAC, and more) and crypto-grade random number generators. Please see docs 4 | at doc/us/index.html or http://luacrypto.luaforge.net/. 5 | -------------------------------------------------------------------------------- /config: -------------------------------------------------------------------------------- 1 | # Installation directories 2 | # System's libraries directory (where binary libraries are installed) 3 | LUA_LIBDIR= /usr/local/lib/lua/5.0 4 | # Lua includes directory 5 | LUA_INC= /usr/local/include 6 | 7 | # OS dependent 8 | LIB_OPTION= -shared #for Linux 9 | #LIB_OPTION= -bundle -undefined dynamic_lookup #for MacOS X 10 | 11 | # Lua version number (first and second digits of target version) 12 | LUA_VERSION_NUM= 500 13 | LIBNAME= $T.so.$V 14 | COMPAT_DIR= ../compat/src 15 | 16 | ########## 17 | # LuaCrypto engine (openssl or gcrypt - not used yet) 18 | #LUACRYPTO_ENGINE= gcrypt 19 | ### OpenSSL 20 | LUACRYPTO_LIBS= -L/usr/local/openssl/lib -lcrypto -lssl 21 | LUACRYPTO_INCS= -I/usr/local/openssl/include -DCRYPTO_OPENSSL=1 22 | ### gcrypt 23 | #LUACRYPTO_LIBS= $(shell libgcrypt-config --libs) 24 | #LUACRYPTO_INCS= $(shell libgcrypt-config --cflags) -DCRYPTO_GCRYPT=1 25 | 26 | # Compilation directives 27 | WARN= -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings 28 | INCS= -I$(LUA_INC) -I$(COMPAT_DIR) 29 | CFLAGS= $(WARN) $(LUACRYPTO_INCS) $(INCS) 30 | CC= gcc 31 | -------------------------------------------------------------------------------- /doc/us/examples.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | LuaCrypto: A Lua frontend to OpenSSL 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 17 |
LuaCrypto
18 |
A Lua frontend to OpenSSL
19 |
20 | 21 |
22 | 23 | 55 | 56 |
57 | 58 | 59 |

Example

60 | 61 | Below is a sample displaying the basic use of the library. 62 | 63 |
 64 | local crypto = require("crypto")
 65 | local evp = require("crypto.evp")
 66 | local hmac = require("crypto.hmac")
 67 | 
 68 | assert(io.input(some_file))
 69 | local md5_of_some_file = evp.digest("md5", io.read("*all"))
 70 |    
 71 | assert(io.input(some_file))
 72 | local hmac_of_some_file = hmac.digest("sha1", io.read("*all"), "hmackey")
 73 | 
74 | 75 | And here is a sample of the object interface to the code. 76 | 77 |
 78 | require("crypto")
 79 | 
 80 | local evp = crypto.evp.new("md5")
 81 | for line in io.lines(some_file) do 
 82 |     evp:update(line)
 83 | end
 84 | local md5_of_some_file = evp:digest()
 85 | 
86 | 87 |
88 | 89 |
90 | 91 |
92 |

Valid XHTML 1.0!

93 |

94 | $Id: examples.html,v 1.1 2006-08-25 03:24:17 nezroy Exp $ 95 |

96 |
97 | 98 |
99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /doc/us/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | LuaCrypto: A Lua frontend to OpenSSL 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 17 |
LuaCrypto
18 |
A Lua frontend to OpenSSL
19 |
20 | 21 |
22 | 23 | 55 | 56 |
57 |

Overview

58 | 59 |

LuaCrypto provides a Lua frontend to the OpenSSL cryptographic library. The OpenSSL features that are currently exposed are digests (MD5, SHA-1, HMAC, and more) and crypto-grade random number generators.

60 | 61 |

62 | LuaCrypto is free software and uses the same license as Lua 5.0. It is currently a stand-alone component with the goal of eventually becoming part of the Kepler Project.

63 | 64 |

Status

65 | 66 |

Current version is 0.2.0. It was developed for Lua 5.1 but it is compatible with Lua 5.0 through the use of Compat-5.1.

67 | 68 |

Download

69 | 70 |

LuaCrypto can be downloaded from its Lua Forge page.

71 | 72 |

Dependencies

73 | 74 | 78 | 79 |

History

80 | 81 |
82 |
0.2.0 [24/Aug/2006]
83 |
Added random support.
84 |
Removed Lua stub files and collapsed modules.
85 |
Changed all supporting materials (documentation, build, etc.) to Kepler standards.
86 | 87 |
0.1.1 [22/Jan/2006]
88 |
Added Lua 5.0/Compat-5.1 support.
89 | 90 |
0.1.0 [13/Jan/2006]
91 |
Initial release.
92 |
93 | 94 |

Credits

95 | 96 |

Much of the original release was based on the lmd5 project, written by Luiz Henrique de Figueiredo. More recent versions were based on existing Kepler components and also incorporate changes contributed by Mark Edgar.

97 | 98 |

Contact

99 | 100 |

For more information please contact me. Comments are welcome!

101 | 102 |
103 | 104 |
105 | 106 |
107 |

108 | Valid XHTML 1.0!

109 |

$Id: index.html,v 1.2 2006-08-25 03:37:51 nezroy Exp $

110 |
111 | 112 |
113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /doc/us/license.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | LuaCrypto: A Lua frontend to OpenSSL 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 17 |
LuaCrypto
18 |
A Lua frontend to OpenSSL
19 |
20 | 21 |
22 | 23 | 55 | 56 |
57 | 58 |

License

59 | 60 |

LuaCrypto is free software: it can be used for both academic and 61 | commercial purposes at absolutely no cost. There are no royalties 62 | or GNU-like "copyleft" restrictions. LuaCrypto qualifies as Open 64 | Source software. Its licenses are compatible with GPL. LuaCrypto is not 66 | in the public domain and Keith Howe keeps its copyright. The 67 | legal details are below.

68 | 69 |

The spirit of the license is that you are free to use LuaCrypto 70 | for any purpose at no cost without having to ask us. The only 71 | requirement is that if you do use LuaCrypto, then you should give 72 | us credit by including the appropriate copyright notice somewhere 73 | in your product or its documentation.

74 | 75 |

The LuaCrypto library is designed and implemented by Keith Howe. The implementation is not derived from licensed software.

76 | 77 |
78 |

Copyright © 2006 Keith Howe.

79 | 80 |

Permission is hereby granted, free of charge, to any person 81 | obtaining a copy of this software and associated documentation 82 | files (the "Software"), to deal in the Software without 83 | restriction, including without limitation the rights to use, copy, 84 | modify, merge, publish, distribute, sublicense, and/or sell copies 85 | of the Software, and to permit persons to whom the Software is 86 | furnished to do so, subject to the following conditions:

87 | 88 |

The above copyright notice and this permission notice shall be 89 | included in all copies or substantial portions of the Software.

90 | 91 |

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 92 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 93 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 94 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 95 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 96 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 97 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 98 | SOFTWARE.

99 | 100 |

 

101 |

 

102 | 103 |
104 | 105 |
106 | 107 |
108 |

109 | Valid XHTML 1.0!

110 |

$Id: license.html,v 1.1 2006-08-25 03:24:17 nezroy Exp $

111 |
112 | 113 |
114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /doc/us/luacrypto-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luaforge/luacrypto/fbc306b30b883e8aecc3b675104108b5be380cc5/doc/us/luacrypto-128.png -------------------------------------------------------------------------------- /doc/us/manual.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | LuaCrypto: A Lua frontend to OpenSSL 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 17 |
LuaCrypto
18 |
A Lua frontend to OpenSSL
19 |
20 | 21 |
22 | 23 | 55 | 56 |
57 |

Introduction

58 | 59 |

LuaCrypto is a Lua frontend to the OpenSSL cryptographic library. The OpenSSL features that are currently exposed are digests (MD5, SHA-1, HMAC, and more) and crypto-grade random number generators.

60 | 61 |

The API tries to hide the OpenSSL setup and teardown, so in most cases it is not simply a pass-through to the existing OpenSSL API. Since this is still a very early version of the software, the API may undergo significant future changes! You have been warned.

62 | 63 |

Building

64 | 65 |

LuaCrypto could be built to Lua 5.0 or to Lua 5.1. In both cases, the language library and headers files for the target version must be installed properly.

66 | 67 |

LuaCrypto offers a Makefile and a separate configuration file, 68 | config, which should be edited to suit your installation before runnig make. The file has some definitions like paths to the external libraries, compiler options and the like. In particular, you must set the correct path to your installed OpenSSL libraries. Another important setting is the version of Lua language, which is not obtained from the installed software.

69 | 70 |

Installation

71 | 72 |

The LuaCrypto compiled binary should be copied to a directory in your C path. Lua 5.0 users should install Compat-5.1 also.

73 | 74 |

Reference

75 | 76 |

Parameters

77 |
78 |
dtype
79 |
This parameter is always a string naming the hashing algorithm to use for a digest operation. The list of supported algorithms may change with each version of the OpenSSL library. Refer to the OpenSSL documentation for a complete and up to date list. As of 0.9.7, the supported types are: 80 |
    81 |
  • md5
  • 82 |
  • md4
  • 83 |
  • md2
  • 84 |
  • sha1
  • 85 |
  • sha
  • 86 |
  • mdc2
  • 87 |
  • ripemd160
  • 88 |
89 |
90 | 91 |

Message Digest (EVP) - crypto.evp

92 |
93 |
crypto.evp.digest(dtype, string [, raw])
94 |
This function generates the message digest of the input string and returns it. The hashing algorithm to use is specified by dtype. The optional raw flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the message digest, or formatted as a hexadecimal string (the default).
95 | 96 |
crypto.evp.new(dtype)
97 |
Creates a new EVP message digest object using the algorithm specified by dtype.
98 | 99 |
evp:reset()
100 |
Resets the EVP message digest object to a clean slate.
101 | 102 |
evp:clone()
103 |
Returns a new message digest object which is a clone of the object and its current state, including any data loaded to this point.
104 | 105 |
evp:update(string)
106 |
Appends the data in string to the current internal data set to be hashed. Returns the object so that it can be reused in nested calls.
107 | 108 |
evp:digest([string] [, raw])
109 |
Generates the message digest for the loaded data, optionally appending on new data provided by string prior to hashing. The optional raw flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the message digest, or formatted as a hexadecimal string (the default).
110 |
111 | 112 |

HMAC - crypto.hmac

113 |
114 |
crypto.hmac.digest(dtype, string, key [, raw])
115 |
This function returns the HMAC of the string. The hashing algorithm to use is specified by dtype. The value provided in key will be used as the seed for the HMAC generation. The optional raw flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the HMAC or formatted as a hexadecimal string (the default).
116 | 117 |
crypto.hmac.new(dtype, key)
118 |
Creates a new HMAC object using the algorithm specified by type. The HMAC seed key to use is provided by key.
119 | 120 |
hmac:reset()
121 |
Resets the HMAC object to a clean slate.
122 | 123 |
hmac:clone()
124 |
Returns a new HMAC object which is a clone of the object and its current state, including data loaded to this point. DOES NOT WORK YET. Just returns a new pointer to the same object.
125 | 126 |
hmac:update(string)
127 |
Appends the data in string to the current internal data set to be hashed.
128 | 129 |
hmac:digest([string] [, raw])
130 |
Generates the HMAC for the loaded data, optionally appending on new data provided by string prior to hashing. The optional raw flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the message digest or formatted as a hexadecimal string (the default). Note that you can only run this method once on an object; running it a second time will product a bogus HMAC because the internal state is irrecovably destroyed after the first call.
131 |
132 | 133 |
134 | 135 |
136 | 137 |
138 |

Valid XHTML 1.0!

139 |

140 | $Id: manual.html,v 1.1 2006-08-25 03:24:17 nezroy Exp $ 141 |

142 |
143 | 144 |
145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /htdocs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | luacrypto homepage 5 | 6 | 7 | 8 |

Table of Contents

9 |
    10 |
  1. Introduction
      11 |
    1. Downloads
    2. 12 |
  2. 13 |
  3. Requirements
  4. 14 |
  5. Installation
  6. 15 |
  7. Credits
  8. 16 |
  9. Usage
  10. 17 |
18 | 19 |

Introduction

20 |

This project provides Lua bindings for the OpenSSL crypto libraries. libcrypto provides digest functions, such as MD5, SHA-1, and HMAC; cipher functions, such as RC5 and Blowfish; public key crypto, such as RSA and Diffie-Hellman; and some other assorted tools (i.e. random number generation).

21 | 22 |

Currently only the digest functions are mapped by this Lua binding.

23 | 24 |

Downloads

25 |

The latest version of luacrypto is 0.1.1, written by Keith Howe <nezroy@luaforge.net>

26 | 29 | 30 |

Requirements

31 | 35 | 36 |

Installation

37 |

Edit the Makefile and set the following fields to the correct values for your environment:

38 | 50 |

Once configured, run make to build the libraries. Run make install to install the libraries in the correct location. The install will run a test suite if you have set the location of your Lua interpreter. You can run the tests independently with make tests, but you cannot run the tests until after you have run make install.

51 | 52 |

Credits

53 |

Much of this code was heavily inspired by and/or lifted directly from the lmd5 project, written by Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>.

54 |

The Compat-5.1 library written by the folks at the Kepler Project is also included for Lua 5.0 support.

55 | 56 |

Usage

57 |

See the documentation for more info.

58 | 59 | 60 | -------------------------------------------------------------------------------- /src/lcrypto.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcrypto.c,v 1.3 2006-09-04 20:32:57 nezroy Exp $ 3 | ** See Copyright Notice in license.html 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "lua.h" 13 | #include "lauxlib.h" 14 | #if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 15 | #include "compat-5.1.h" 16 | #endif 17 | 18 | #include "lcrypto.h" 19 | 20 | #if CRYPTO_OPENSSL 21 | #define LUACRYPTO_ENGINE "OpenSSL" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #define HANDLER_EVP EVP_MD_CTX 27 | #define HANDLER_HMAC HMAC_CTX 28 | #define DIGEST_TYPE const EVP_MD* 29 | #define DIGEST_BY_NAME(s) EVP_get_digestbyname(s) 30 | #define IS_DIGEST_INVALID(x) (x==NULL) 31 | #define EVP_UPDATE(c,s,len) EVP_DigestUpdate(c, s, len) 32 | #define HMAC_UPDATE(c,s,len) HMAC_Update(c, (unsigned char *)s, len); 33 | #define EVP_CLEANUP(c) EVP_MD_CTX_cleanup(c); 34 | #define HMAC_CLEANUP(c) HMAC_CTX_cleanup(c); 35 | #elif CRYPTO_GCRYPT 36 | #define LUACRYPTO_ENGINE "gcrypt" 37 | #include 38 | #define HANDLER_EVP gcry_md_hd_t 39 | #define HANDLER_HMAC gcry_md_hd_t 40 | #define DIGEST_TYPE int 41 | #define DIGEST_BY_NAME(s) gcry_md_map_name(s) 42 | #define IS_DIGEST_INVALID(x) (x==0) 43 | #define EVP_UPDATE(c,s,len) gcry_md_write(*c, s, len) 44 | #define HMAC_UPDATE(c,s,len) gcry_md_write(*c, s, len) 45 | #define EVP_CLEANUP(c) gcry_md_close(*c) 46 | #define HMAC_CLEANUP(c) gcry_md_close(*c) 47 | #else 48 | #error "LUACRYPTO_DRIVER not supported" 49 | #endif 50 | 51 | LUACRYPTO_API int luaopen_crypto(lua_State *L); 52 | 53 | static char* bin2hex(const unsigned char *digest, size_t written) 54 | { 55 | char * hex = calloc(sizeof(char), written*2 + 1); 56 | unsigned int i; 57 | for (i = 0; i < written; i++) 58 | sprintf(hex + 2*i, "%02x", digest[i]); 59 | return hex; 60 | } 61 | 62 | #if CRYPTO_OPENSSL 63 | static int crypto_error(lua_State *L) 64 | { 65 | char buf[120]; 66 | unsigned long e = ERR_get_error(); 67 | ERR_load_crypto_strings(); 68 | lua_pushnil(L); 69 | lua_pushstring(L, ERR_error_string(e, buf)); 70 | return 2; 71 | } 72 | #endif 73 | 74 | static HANDLER_EVP *evp_pget(lua_State *L, int i) 75 | { 76 | if (luaL_checkudata(L, i, LUACRYPTO_EVPNAME) == NULL) 77 | luaL_typerror(L, i, LUACRYPTO_EVPNAME); 78 | return lua_touserdata(L, i); 79 | } 80 | 81 | static HANDLER_EVP *evp_pnew(lua_State *L) 82 | { 83 | HANDLER_EVP *c = lua_newuserdata(L, sizeof(HANDLER_EVP)); 84 | luaL_getmetatable(L, LUACRYPTO_EVPNAME); 85 | lua_setmetatable(L, -2); 86 | return c; 87 | } 88 | 89 | static int evp_fnew(lua_State *L) 90 | { 91 | HANDLER_EVP *c = NULL; 92 | const char *s = luaL_checkstring(L, 1); 93 | DIGEST_TYPE type = DIGEST_BY_NAME(s); 94 | 95 | if (IS_DIGEST_INVALID(type)) { 96 | luaL_argerror(L, 1, "invalid digest type"); 97 | return 0; 98 | } 99 | 100 | c = evp_pnew(L); 101 | 102 | #if CRYPTO_OPENSSL 103 | EVP_MD_CTX_init(c); 104 | EVP_DigestInit_ex(c, type, NULL); //must return 1 (not checked!) 105 | #elif CRYPTO_GCRYPT 106 | gcry_md_open(c, type, 0); //returns a gcry_error_t (not checked!) 107 | #endif 108 | 109 | return 1; 110 | } 111 | 112 | static int evp_clone(lua_State *L) 113 | { 114 | HANDLER_EVP *c = evp_pget(L, 1); 115 | HANDLER_EVP *d = evp_pnew(L); 116 | 117 | #if CRYPTO_OPENSSL 118 | EVP_MD_CTX_init(d); 119 | EVP_MD_CTX_copy_ex(d, c); 120 | #elif CRYPTO_GCRYPT 121 | gcry_md_copy(d, *c); 122 | #endif 123 | 124 | return 1; 125 | } 126 | 127 | static int evp_reset(lua_State *L) 128 | { 129 | HANDLER_EVP *c = evp_pget(L, 1); 130 | 131 | #if CRYPTO_OPENSSL 132 | const EVP_MD *t = EVP_MD_CTX_md(c); 133 | EVP_MD_CTX_cleanup(c); 134 | EVP_MD_CTX_init(c); 135 | EVP_DigestInit_ex(c, t, NULL); 136 | #elif CRYPTO_GCRYPT 137 | gcry_md_reset(*c); 138 | #endif 139 | 140 | return 0; 141 | } 142 | 143 | static int evp_update(lua_State *L) 144 | { 145 | HANDLER_EVP *c = evp_pget(L, 1); 146 | size_t s_len; 147 | const char *s = luaL_checklstring(L, 2, &s_len); 148 | 149 | EVP_UPDATE(c, s, s_len); 150 | 151 | lua_settop(L, 1); 152 | return 1; 153 | } 154 | 155 | static int evp_digest(lua_State *L) 156 | { 157 | HANDLER_EVP *c = evp_pget(L, 1); 158 | #if CRYPTO_OPENSSL 159 | HANDLER_EVP *d = NULL; 160 | unsigned char digest[EVP_MAX_MD_SIZE]; 161 | #elif CRYPTO_GCRYPT 162 | HANDLER_EVP d = NULL; 163 | unsigned char *digest; 164 | int algo; 165 | #endif 166 | size_t written = 0; 167 | 168 | if (lua_isstring(L, 2)) 169 | { 170 | size_t s_len; 171 | const char *s = luaL_checklstring(L, 2, &s_len); 172 | EVP_UPDATE(c, s, s_len); 173 | } 174 | 175 | #if CRYPTO_OPENSSL 176 | d = EVP_MD_CTX_create(); 177 | EVP_MD_CTX_copy_ex(d, c); 178 | EVP_DigestFinal_ex(d, digest, &written); 179 | EVP_MD_CTX_destroy(d); 180 | #elif CRYPTO_GCRYPT 181 | algo = gcry_md_get_algo(*c); 182 | gcry_md_copy(&d, *c); 183 | gcry_md_final(d); 184 | digest = gcry_md_read(d, algo); 185 | written = gcry_md_get_algo_dlen(algo); 186 | #endif 187 | 188 | if (lua_toboolean(L, 3)) 189 | lua_pushlstring(L, (char *)digest, written); 190 | else 191 | { 192 | char *hex = bin2hex(digest, written); 193 | lua_pushlstring(L, hex, written*2); 194 | free(hex); 195 | } 196 | 197 | #if CRYPTO_GCRYPT 198 | gcry_md_close(d); 199 | #endif 200 | 201 | return 1; 202 | } 203 | 204 | static int evp_tostring(lua_State *L) 205 | { 206 | HANDLER_EVP *c = evp_pget(L, 1); 207 | char s[64]; 208 | sprintf(s, "%s %p", LUACRYPTO_EVPNAME, (void *)c); 209 | lua_pushstring(L, s); 210 | return 1; 211 | } 212 | 213 | static int evp_gc(lua_State *L) 214 | { 215 | HANDLER_EVP *c = evp_pget(L, 1); 216 | EVP_CLEANUP(c); 217 | return 1; 218 | } 219 | 220 | static int evp_fdigest(lua_State *L) 221 | { 222 | const char *type_name = luaL_checkstring(L, 1); 223 | const char *s = luaL_checkstring(L, 2); 224 | DIGEST_TYPE type = DIGEST_BY_NAME(type_name); 225 | size_t written = 0; 226 | #if CRYPTO_OPENSSL 227 | HANDLER_EVP *c = NULL; 228 | unsigned char digest[EVP_MAX_MD_SIZE]; 229 | #elif CRYPTO_GCRYPT 230 | unsigned char digest[gcry_md_get_algo_dlen(type)]; 231 | #endif 232 | 233 | if (IS_DIGEST_INVALID(type)) { 234 | luaL_argerror(L, 1, "invalid digest type"); 235 | return 0; 236 | } 237 | 238 | #if CRYPTO_OPENSSL 239 | c = EVP_MD_CTX_create(); 240 | EVP_DigestInit_ex(c, type, NULL); 241 | EVP_DigestUpdate(c, s, lua_strlen(L, 2)); 242 | EVP_DigestFinal_ex(c, digest, &written); 243 | #elif CRYPTO_GCRYPT 244 | gcry_md_hash_buffer(type,digest,s,lua_strlen(L, 2)); 245 | written = gcry_md_get_algo_dlen(type); 246 | #endif 247 | 248 | if (lua_toboolean(L, 3)) 249 | lua_pushlstring(L, (char *)digest, written); 250 | else 251 | { 252 | char *hex = bin2hex(digest, written); 253 | lua_pushlstring(L, hex, written*2); 254 | free(hex); 255 | } 256 | 257 | return 1; 258 | } 259 | 260 | static HANDLER_HMAC *hmac_pget(lua_State *L, int i) 261 | { 262 | if (luaL_checkudata(L, i, LUACRYPTO_HMACNAME) == NULL) 263 | luaL_typerror(L, i, LUACRYPTO_HMACNAME); 264 | return lua_touserdata(L, i); 265 | } 266 | 267 | static HANDLER_HMAC *hmac_pnew(lua_State *L) 268 | { 269 | HANDLER_HMAC *c = lua_newuserdata(L, sizeof(HANDLER_HMAC)); 270 | luaL_getmetatable(L, LUACRYPTO_HMACNAME); 271 | lua_setmetatable(L, -2); 272 | return c; 273 | } 274 | 275 | static int hmac_fnew(lua_State *L) 276 | { 277 | HANDLER_HMAC *c = hmac_pnew(L); 278 | const char *s = luaL_checkstring(L, 1); 279 | size_t k_len; 280 | const char *k = luaL_checklstring(L, 2, &k_len); 281 | DIGEST_TYPE type = DIGEST_BY_NAME(s); 282 | 283 | if (IS_DIGEST_INVALID(type)) { 284 | luaL_argerror(L, 1, "invalid digest type"); 285 | return 0; 286 | } 287 | 288 | #if CRYPTO_OPENSSL 289 | HMAC_CTX_init(c); 290 | HMAC_Init_ex(c, k, k_len, type, NULL); 291 | #elif CRYPTO_GCRYPT 292 | gcry_md_open(c, type, GCRY_MD_FLAG_HMAC); 293 | gcry_md_setkey(*c, k, k_len); 294 | #endif 295 | 296 | return 1; 297 | } 298 | 299 | static int hmac_clone(lua_State *L) 300 | { 301 | HANDLER_HMAC *c = hmac_pget(L, 1); 302 | HANDLER_HMAC *d = hmac_pnew(L); 303 | 304 | #if CRYPTO_OPENSSL 305 | *d = *c; 306 | #elif CRYPTO_GCRYPT 307 | gcry_md_copy(d, *c); 308 | #endif 309 | 310 | return 1; 311 | } 312 | 313 | static int hmac_reset(lua_State *L) 314 | { 315 | HANDLER_HMAC *c = hmac_pget(L, 1); 316 | 317 | #if CRYPTO_OPENSSL 318 | HMAC_Init_ex(c, NULL, 0, NULL, NULL); 319 | #elif CRYPTO_GCRYPT 320 | gcry_md_reset(*c); 321 | #endif 322 | 323 | return 0; 324 | } 325 | 326 | static int hmac_update(lua_State *L) 327 | { 328 | HANDLER_HMAC *c = hmac_pget(L, 1); 329 | size_t s_len; 330 | const char *s = luaL_checklstring(L, 2, &s_len); 331 | 332 | HMAC_UPDATE(c, s, s_len); 333 | 334 | lua_settop(L, 1); 335 | return 1; 336 | } 337 | 338 | static int hmac_digest(lua_State *L) 339 | { 340 | HANDLER_HMAC *c = hmac_pget(L, 1); 341 | size_t written = 0; 342 | #if CRYPTO_OPENSSL 343 | unsigned char digest[EVP_MAX_MD_SIZE]; 344 | #elif CRYPTO_GCRYPT 345 | HANDLER_HMAC d; 346 | unsigned char *digest; 347 | int algo; 348 | #endif 349 | 350 | if (lua_isstring(L, 2)) 351 | { 352 | size_t s_len; 353 | const char *s = luaL_checklstring(L, 2, &s_len); 354 | HMAC_UPDATE(c, s, s_len); 355 | } 356 | 357 | #if CRYPTO_OPENSSL 358 | HMAC_Final(c, digest, &written); 359 | #elif CRYPTO_GCRYPT 360 | algo = gcry_md_get_algo(*c); 361 | gcry_md_copy(&d, *c); 362 | gcry_md_final(d); 363 | digest = gcry_md_read(d, algo); 364 | written = gcry_md_get_algo_dlen(algo); 365 | #endif 366 | 367 | if (lua_toboolean(L, 3)) 368 | lua_pushlstring(L, (char *)digest, written); 369 | else 370 | { 371 | char *hex = bin2hex(digest, written); 372 | lua_pushlstring(L, hex, written*2); 373 | free(hex); 374 | } 375 | 376 | #if CRYPTO_GCRYPT 377 | gcry_md_close(d); 378 | #endif 379 | 380 | return 1; 381 | } 382 | 383 | static int hmac_tostring(lua_State *L) 384 | { 385 | HANDLER_HMAC *c = hmac_pget(L, 1); 386 | char s[64]; 387 | sprintf(s, "%s %p", LUACRYPTO_HMACNAME, (void *)c); 388 | lua_pushstring(L, s); 389 | return 1; 390 | } 391 | 392 | static int hmac_gc(lua_State *L) 393 | { 394 | HANDLER_HMAC *c = hmac_pget(L, 1); 395 | HMAC_CLEANUP(c); 396 | return 1; 397 | } 398 | 399 | static int hmac_fdigest(lua_State *L) 400 | { 401 | HANDLER_HMAC c; 402 | size_t written = 0; 403 | const char *t = luaL_checkstring(L, 1); 404 | size_t s_len; 405 | const char *s = luaL_checklstring(L, 2, &s_len); 406 | size_t k_len; 407 | const char *k = luaL_checklstring(L, 3, &k_len); 408 | DIGEST_TYPE type = DIGEST_BY_NAME(t); 409 | #if CRYPTO_OPENSSL 410 | unsigned char digest[EVP_MAX_MD_SIZE]; 411 | #elif CRYPTO_GCRYPT 412 | unsigned char *digest; 413 | #endif 414 | 415 | if (IS_DIGEST_INVALID(type)) { 416 | luaL_argerror(L, 1, "invalid digest type"); 417 | return 0; 418 | } 419 | 420 | #if CRYPTO_OPENSSL 421 | HMAC_CTX_init(&c); 422 | HMAC_Init_ex(&c, k, k_len, type, NULL); 423 | HMAC_Update(&c, (unsigned char *)s, s_len); 424 | HMAC_Final(&c, digest, &written); 425 | #elif CRYPTO_GCRYPT 426 | gcry_md_open(&c, type, GCRY_MD_FLAG_HMAC); 427 | gcry_md_setkey(c, k, k_len); 428 | gcry_md_write(c, s, s_len); 429 | gcry_md_final(c); 430 | digest = gcry_md_read(c,type); 431 | written = gcry_md_get_algo_dlen(type); 432 | #endif 433 | 434 | if (lua_toboolean(L, 4)) 435 | lua_pushlstring(L, (char *)digest, written); 436 | else 437 | { 438 | char *hex = bin2hex(digest,written); 439 | lua_pushlstring(L, hex, written*2); 440 | free(hex); 441 | } 442 | 443 | #if CRYPTO_GCRYPT 444 | gcry_md_close(c); 445 | #endif 446 | 447 | return 1; 448 | } 449 | 450 | #if CRYPTO_OPENSSL 451 | static int rand_do_bytes(lua_State *L, int (*bytes)(unsigned char *, int)) 452 | { 453 | size_t count = luaL_checkint(L, 1); 454 | unsigned char tmp[256], *buf = tmp; 455 | if (count > sizeof tmp) 456 | buf = malloc(count); 457 | if (!buf) 458 | return luaL_error(L, "out of memory"); 459 | else if (!bytes(buf, count)) 460 | return crypto_error(L); 461 | lua_pushlstring(L, (char *)buf, count); 462 | if (buf != tmp) 463 | free(buf); 464 | return 1; 465 | } 466 | 467 | static int rand_bytes(lua_State *L) 468 | { 469 | return rand_do_bytes(L, RAND_bytes); 470 | } 471 | 472 | static int rand_pseudo_bytes(lua_State *L) 473 | { 474 | return rand_do_bytes(L, RAND_pseudo_bytes); 475 | } 476 | #elif CRYPTO_GCRYPT 477 | static int rand_do_bytes(lua_State *L, enum gcry_random_level level) 478 | { 479 | size_t count = luaL_checkint(L, 1); 480 | void* buf = gcry_random_bytes/*_secure*/(count, level); 481 | 482 | gcry_fast_random_poll(); 483 | 484 | lua_pushlstring(L, (char *)buf, count); 485 | 486 | return 1; 487 | } 488 | 489 | static int rand_bytes(lua_State *L) 490 | { 491 | return rand_do_bytes(L, GCRY_VERY_STRONG_RANDOM); 492 | } 493 | 494 | static int rand_pseudo_bytes(lua_State *L) 495 | { 496 | return rand_do_bytes(L, GCRY_STRONG_RANDOM); 497 | } 498 | #endif 499 | 500 | static int rand_add(lua_State *L) 501 | { 502 | size_t num; 503 | const void *buf = luaL_checklstring(L, 1, &num); 504 | #if CRYPTO_OPENSSL 505 | double entropy = (double)luaL_optnumber(L, 2, num); 506 | RAND_add(buf, num, entropy); 507 | #elif CRYPTO_GCRYPT 508 | gcry_random_add_bytes(buf, num, -1); // unknown quality 509 | #endif 510 | return 0; 511 | } 512 | 513 | static int rand_status(lua_State *L) 514 | { 515 | #if CRYPTO_OPENSSL 516 | lua_pushboolean(L, RAND_status()); 517 | #elif CRYPTO_GCRYPT 518 | lua_pushboolean(L, 1); //feature not available AFAIK 519 | #endif 520 | return 1; 521 | } 522 | 523 | enum { WRITE_FILE_COUNT = 1024 }; 524 | static int rand_load(lua_State *L) 525 | { 526 | const char *name = luaL_optstring(L, 1, NULL); 527 | #if CRYPTO_OPENSSL 528 | char tmp[256]; 529 | int n; 530 | if (!name && !(name = RAND_file_name(tmp, sizeof tmp))) 531 | return crypto_error(L); 532 | n = RAND_load_file(name, WRITE_FILE_COUNT); 533 | if (n == 0) 534 | return crypto_error(L); 535 | lua_pushnumber(L, n); 536 | #elif CRYPTO_GCRYPT 537 | if (name != NULL) 538 | gcry_control(GCRYCTL_SET_RANDOM_SEED_FILE, name); 539 | lua_pushnumber(L, 0.0); 540 | #endif 541 | return 1; 542 | } 543 | 544 | static int rand_write(lua_State *L) 545 | { 546 | const char *name = luaL_optstring(L, 1, NULL); 547 | #if CRYPTO_OPENSSL 548 | char tmp[256]; 549 | int n; 550 | if (!name && !(name = RAND_file_name(tmp, sizeof tmp))) 551 | return crypto_error(L); 552 | n = RAND_write_file(name); 553 | if (n == 0) 554 | return crypto_error(L); 555 | lua_pushnumber(L, n); 556 | #elif CRYPTO_GCRYPT 557 | /* this is a BUG() in gcrypt. not sure if it refers to the lib or to 558 | the caller, but it does not work (to set twice this file) */ 559 | /* 560 | if (name != NULL) 561 | gcry_control(GCRYCTL_SET_RANDOM_SEED_FILE,name); 562 | */ 563 | gcry_control(GCRYCTL_UPDATE_RANDOM_SEED_FILE); 564 | lua_pushnumber(L, 0.0); 565 | #endif 566 | return 1; 567 | } 568 | 569 | static int rand_cleanup(lua_State *L) 570 | { 571 | #if CRYPTO_OPENSSL 572 | RAND_cleanup(); 573 | #elif CRYPTO_GCRYPT 574 | /* not completely sure there is nothing to do here... */ 575 | #endif 576 | return 0; 577 | } 578 | 579 | /* 580 | ** Create a metatable and leave it on top of the stack. 581 | */ 582 | LUACRYPTO_API int luacrypto_createmeta (lua_State *L, const char *name, const luaL_reg *methods) { 583 | if (!luaL_newmetatable (L, name)) 584 | return 0; 585 | 586 | /* define methods */ 587 | luaL_openlib (L, NULL, methods, 0); 588 | 589 | /* define metamethods */ 590 | lua_pushliteral (L, "__index"); 591 | lua_pushvalue (L, -2); 592 | lua_settable (L, -3); 593 | 594 | lua_pushliteral (L, "__metatable"); 595 | lua_pushliteral (L, LUACRYPTO_PREFIX"you're not allowed to get this metatable"); 596 | lua_settable (L, -3); 597 | 598 | return 1; 599 | } 600 | 601 | /* 602 | ** Create metatables for each class of object. 603 | */ 604 | static void create_metatables (lua_State *L) 605 | { 606 | struct luaL_reg evp_functions[] = { 607 | { "digest", evp_fdigest }, 608 | { "new", evp_fnew }, 609 | {NULL, NULL}, 610 | }; 611 | struct luaL_reg evp_methods[] = { 612 | { "__tostring", evp_tostring }, 613 | { "__gc", evp_gc }, 614 | { "clone", evp_clone }, 615 | { "digest", evp_digest }, 616 | { "reset", evp_reset }, 617 | { "tostring", evp_tostring }, 618 | { "update", evp_update }, 619 | {NULL, NULL}, 620 | }; 621 | struct luaL_reg hmac_functions[] = { 622 | { "digest", hmac_fdigest }, 623 | { "new", hmac_fnew }, 624 | { NULL, NULL } 625 | }; 626 | struct luaL_reg hmac_methods[] = { 627 | { "__tostring", hmac_tostring }, 628 | { "__gc", hmac_gc }, 629 | { "clone", hmac_clone }, 630 | { "digest", hmac_digest }, 631 | { "reset", hmac_reset }, 632 | { "tostring", hmac_tostring }, 633 | { "update", hmac_update }, 634 | { NULL, NULL } 635 | }; 636 | struct luaL_reg rand_functions[] = { 637 | { "bytes", rand_bytes }, 638 | { "pseudo_bytes", rand_pseudo_bytes }, 639 | { "add", rand_add }, 640 | { "seed", rand_add }, 641 | { "load", rand_load }, 642 | { "write", rand_write }, 643 | { "status", rand_status }, 644 | { "cleanup", rand_cleanup }, 645 | { NULL, NULL } 646 | }; 647 | 648 | luaL_openlib (L, LUACRYPTO_EVPNAME, evp_functions, 0); 649 | luacrypto_createmeta(L, LUACRYPTO_EVPNAME, evp_methods); 650 | luaL_openlib (L, LUACRYPTO_HMACNAME, hmac_functions, 0); 651 | luacrypto_createmeta(L, LUACRYPTO_HMACNAME, hmac_methods); 652 | luaL_openlib (L, LUACRYPTO_RANDNAME, rand_functions, 0); 653 | lua_pop (L, 3); 654 | } 655 | 656 | /* 657 | ** Define the metatable for the object on top of the stack 658 | */ 659 | LUACRYPTO_API void luacrypto_setmeta (lua_State *L, const char *name) { 660 | luaL_getmetatable (L, name); 661 | lua_setmetatable (L, -2); 662 | } 663 | 664 | /* 665 | ** Assumes the table is on top of the stack. 666 | */ 667 | LUACRYPTO_API void luacrypto_set_info (lua_State *L) { 668 | lua_pushliteral (L, "_COPYRIGHT"); 669 | lua_pushliteral (L, "Copyright (C) 2005-2006 Keith Howe"); 670 | lua_settable (L, -3); 671 | lua_pushliteral (L, "_DESCRIPTION"); 672 | lua_pushliteral (L, "LuaCrypto is a Lua wrapper for OpenSSL/gcrypt"); 673 | lua_settable (L, -3); 674 | lua_pushliteral (L, "_VERSION"); 675 | lua_pushliteral (L, "LuaCrypto 0.3.0"); 676 | lua_settable (L, -3); 677 | lua_pushliteral (L, "_ENGINE"); 678 | lua_pushliteral (L, LUACRYPTO_ENGINE); 679 | lua_settable (L, -3); 680 | } 681 | 682 | /* 683 | ** Creates the metatables for the objects and registers the 684 | ** driver open method. 685 | */ 686 | LUACRYPTO_API int luaopen_crypto(lua_State *L) 687 | { 688 | #if CRYPTO_OPENSSL 689 | if (OPENSSL_VERSION_NUMBER < 0x000907000L) 690 | return luaL_error(L, "OpenSSL version is too old; requires 0.9.7 or higher"); 691 | OpenSSL_add_all_digests(); 692 | #elif CRYPTO_GCRYPT 693 | gcry_check_version("1.2.2"); 694 | gcry_control (GCRYCTL_DISABLE_SECMEM, 0); 695 | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 696 | #endif 697 | 698 | struct luaL_reg core[] = { 699 | {NULL, NULL}, 700 | }; 701 | create_metatables (L); 702 | luaL_openlib (L, LUACRYPTO_CORENAME, core, 0); 703 | luacrypto_set_info (L); 704 | return 1; 705 | } 706 | -------------------------------------------------------------------------------- /src/lcrypto.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcrypto.h,v 1.2 2006-08-25 03:28:32 nezroy Exp $ 3 | ** See Copyright Notice in license.html 4 | */ 5 | 6 | #ifndef _LUACRYPTO_ 7 | #define _LUACRYPTO_ 8 | 9 | #ifndef LUACRYPTO_API 10 | #define LUACRYPTO_API LUA_API 11 | #endif 12 | 13 | #define LUACRYPTO_PREFIX "LuaCrypto: " 14 | #define LUACRYPTO_CORENAME "crypto" 15 | #define LUACRYPTO_EVPNAME "crypto.evp" 16 | #define LUACRYPTO_HMACNAME "crypto.hmac" 17 | #define LUACRYPTO_RANDNAME "crypto.rand" 18 | 19 | LUACRYPTO_API int luacrypto_createmeta (lua_State *L, const char *name, const luaL_reg *methods); 20 | LUACRYPTO_API void luacrypto_setmeta (lua_State *L, const char *name); 21 | LUACRYPTO_API void luacrypto_set_info (lua_State *L); 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /tests/message: -------------------------------------------------------------------------------- 1 | This is a sample message to use for hashing tests. 2 | -------------------------------------------------------------------------------- /tests/rand.lua: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/lua50 2 | 3 | --[[ 4 | -- $Id: rand.lua,v 1.1 2006-08-25 03:24:17 nezroy Exp $ 5 | -- See Copyright Notice in license.html 6 | --]] 7 | 8 | require "crypto" 9 | local rand = crypto.rand 10 | 11 | print("RAND version: " .. crypto._VERSION) 12 | print("") 13 | 14 | local SEEDFILE = "tmp.rnd" 15 | 16 | if rand.load(SEEDFILE) then 17 | print("loaded previous random seed") 18 | end 19 | 20 | if rand.status() then 21 | print("ready to generate") 22 | print("") 23 | else 24 | print("The PRNG does not yet have enough data.") 25 | local prompt = "Please type some random characters and press ENTER: " 26 | repeat 27 | io.write(prompt); io.flush() 28 | local line = io.read("*l") 29 | -- entropy of English is 1.1 bits per character 30 | rand.add(line, string.len(line) * 1.1 / 8) 31 | prompt = "More: " 32 | until rand.status() 33 | end 34 | 35 | local N = 20 36 | local S = 5 37 | 38 | print(string.format("generating %d sets of %d random bytes using pseudo_bytes()", S, N)) 39 | for i = 1, S do 40 | local data = assert(rand.pseudo_bytes(N)) 41 | print(table.concat({string.byte(data, 1, N)}, ",")) 42 | end 43 | print("") 44 | 45 | print(string.format("generating %d sets of %d random bytes using bytes()", S, N)) 46 | for i = 1, S do 47 | local data = assert(rand.bytes(N)) 48 | print(table.concat({string.byte(data, 1, N)}, ",")) 49 | end 50 | print("") 51 | 52 | print("saving seed in " .. SEEDFILE) 53 | print("") 54 | rand.write(SEEDFILE) 55 | 56 | -- don't leave any sensitive data lying around in memory 57 | print("cleaning up state") 58 | print("") 59 | rand.cleanup() 60 | -------------------------------------------------------------------------------- /tests/test.lua: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/lua50 2 | 3 | --[[ 4 | -- $Id: test.lua,v 1.4 2006-09-04 20:32:57 nezroy Exp $ 5 | -- See Copyright Notice in license.html 6 | --]] 7 | 8 | require("crypto") 9 | local evp = crypto.evp 10 | local hmac = crypto.hmac 11 | 12 | md5_KNOWN = "09920f6f666f8e7b09a8d00bd4d06873" 13 | sha1_KNOWN = "d6ed6e26ebeb37ba0792ec75a3d0b4dcec279d25" 14 | hmac_KNOWN = "70a7ea81a287d094c534cdd67be82e85066e13be" 15 | 16 | print("LuaCrypto version: " .. crypto._VERSION) 17 | print("LuaCrypto engine: " .. crypto._ENGINE) 18 | print("") 19 | 20 | function report(w, s, F, t) 21 | print(w, s .. " " .. F) 22 | assert(s == _G[t .. "_KNOWN"]) 23 | end 24 | 25 | F = arg[1] 26 | for i, t in ipairs({"sha1", "md5", "sha1", "hmac"}) do 27 | print("testing " .. t) 28 | local d 29 | if (t == "hmac") then 30 | d = hmac.new("sha1", "luacrypto") 31 | else 32 | d = evp.new(t) 33 | end 34 | 35 | assert(io.input(F)) 36 | report("all", d:digest(io.read("*all")), F, t) 37 | 38 | d:reset(d) 39 | 40 | assert(io.input(F)) 41 | while true do 42 | local c = io.read(1) 43 | if c == nil then break end 44 | d:update(c) 45 | end 46 | report("loop", d:digest(), F, t) 47 | if (t ~= "hmac") then 48 | report("again", d:digest(), F, t) 49 | assert(io.input(F)) 50 | report("alone", evp.digest(t, io.read("*all")), F, t) 51 | else 52 | assert(io.input(F)) 53 | report("alone", hmac.digest("sha1", io.read("*all"), "luacrypto"), F, t); 54 | end 55 | 56 | assert(io.input(F)) 57 | d:reset() 58 | while true do 59 | local c = io.read(math.random(1, 16)) 60 | if c == nil then break end 61 | d:update(c) 62 | end 63 | report("reset", d:digest(d), F, t) 64 | report("known", _G[t .. "_KNOWN"], F, t) 65 | print("") 66 | end 67 | 68 | print("all tests passed") 69 | --------------------------------------------------------------------------------