~ubuntu-branches/ubuntu/quantal/genometools/quantal-backports

« back to all changes in this revision

Viewing changes to src/external/md5-1.1.2/src/md5lib.c

  • Committer: Package Import Robot
  • Author(s): Sascha Steinbiss
  • Date: 2012-07-09 14:10:23 UTC
  • Revision ID: package-import@ubuntu.com-20120709141023-juuu4spm6chqsf9o
Tags: upstream-1.4.1
ImportĀ upstreamĀ versionĀ 1.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
*  $Id: md5lib.c,v 1.10 2008/05/12 20:51:27 carregal Exp $
 
3
*  Cryptographic and Hash functions for Lua
 
4
*  @author  Roberto Ierusalimschy
 
5
*/
 
6
 
 
7
 
 
8
#include <stdlib.h>
 
9
#include <string.h>
 
10
#include <time.h>
 
11
 
 
12
#include <lua.h>
 
13
#include <lauxlib.h>
 
14
 
 
15
#if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501
 
16
#include "compat-5.1.h"
 
17
#endif
 
18
 
 
19
#include "md5.h"
 
20
 
 
21
 
 
22
/**
 
23
*  Hash function. Returns a hash for a given string.
 
24
*  @param message: arbitrary binary string.
 
25
*  @return  A 128-bit hash string.
 
26
*/
 
27
static int lmd5 (lua_State *L) {
 
28
  char buff[16];
 
29
  size_t l;
 
30
  const char *message = luaL_checklstring(L, 1, &l);
 
31
  md5(message, l, buff);
 
32
  lua_pushlstring(L, buff, 16L);
 
33
  return 1;
 
34
}
 
35
 
 
36
 
 
37
/**
 
38
*  X-Or. Does a bit-a-bit exclusive-or of two strings.
 
39
*  @param s1: arbitrary binary string.
 
40
*  @param s2: arbitrary binary string with same length as s1.
 
41
*  @return  a binary string with same length as s1 and s2,
 
42
*   where each bit is the exclusive-or of the corresponding bits in s1-s2.
 
43
*/
 
44
static int ex_or (lua_State *L) {
 
45
  size_t l1, l2;
 
46
  const char *s1 = luaL_checklstring(L, 1, &l1);
 
47
  const char *s2 = luaL_checklstring(L, 2, &l2);
 
48
  luaL_Buffer b;
 
49
  luaL_argcheck( L, l1 == l2, 2, "lengths must be equal" );
 
50
  luaL_buffinit(L, &b);
 
51
  while (l1--) luaL_putchar(&b, (*s1++)^(*s2++));
 
52
  luaL_pushresult(&b);
 
53
  return 1;
 
54
}
 
55
 
 
56
 
 
57
static void checkseed (lua_State *L) {
 
58
  if (lua_isnone(L, 3)) {  /* no seed? */
 
59
    time_t tm = time(NULL);  /* for `random' seed */
 
60
    lua_pushlstring(L, (char *)&tm, sizeof(tm));
 
61
  }
 
62
}
 
63
 
 
64
 
 
65
#define MAXKEY  256
 
66
#define BLOCKSIZE       16
 
67
 
 
68
 
 
69
 
 
70
static int initblock (lua_State *L, const char *seed, int lseed, char *block) {
 
71
  size_t lkey;
 
72
  const char *key = luaL_checklstring(L, 2, &lkey);
 
73
  if (lkey > MAXKEY)
 
74
    luaL_error(L, "key too long (> %d)", MAXKEY);
 
75
  memset(block, 0, BLOCKSIZE);
 
76
  memcpy(block, seed, lseed);
 
77
  memcpy(block+BLOCKSIZE, key, lkey);
 
78
  return (int)lkey+BLOCKSIZE;
 
79
}
 
80
 
 
81
 
 
82
static void codestream (lua_State *L, const char *msg, size_t lmsg,
 
83
                                      char *block, int lblock) {
 
84
  luaL_Buffer b;
 
85
  luaL_buffinit(L, &b);
 
86
  while (lmsg > 0) {
 
87
    char code[BLOCKSIZE];
 
88
    int i;
 
89
    md5(block, lblock, code);
 
90
    for (i=0; i<BLOCKSIZE && lmsg > 0; i++, lmsg--)
 
91
      code[i] ^= *msg++;
 
92
    luaL_addlstring(&b, code, i); 
 
93
    memcpy(block, code, i); /* update seed */
 
94
  }
 
95
  luaL_pushresult(&b);
 
96
}
 
97
 
 
98
 
 
99
static void decodestream (lua_State *L, const char *cypher, size_t lcypher,
 
100
                          char *block, int lblock) {
 
101
  luaL_Buffer b;
 
102
  luaL_buffinit(L, &b);
 
103
  while (lcypher > 0) {
 
104
    char code[BLOCKSIZE];
 
105
    int i;
 
106
    md5(block, lblock, code);  /* update seed */
 
107
    for (i=0; i<BLOCKSIZE && lcypher > 0; i++, lcypher--)
 
108
      code[i] ^= *cypher++;
 
109
    luaL_addlstring(&b, code, i); 
 
110
    memcpy(block, cypher-i, i);
 
111
  }
 
112
  luaL_pushresult(&b);
 
113
}
 
114
 
 
115
 
 
116
/**
 
117
*  Encrypts a string. Uses the hash function md5 in CFB (Cipher-feedback
 
118
*  mode).
 
119
*  @param message: arbitrary binary string to be encrypted.
 
120
*  @param key: arbitrary binary string to be used as a key.
 
121
*  @param [seed]: optional arbitrary binary string to be used as a seed.
 
122
*  if no seed is provided, the function uses the result of
 
123
*  <code>time()</code> as a seed.  
 
124
*  @return  The cyphertext (as a binary string).
 
125
*/
 
126
static int crypt (lua_State *L) {
 
127
  size_t lmsg;
 
128
  const char *msg = luaL_checklstring(L, 1, &lmsg);
 
129
  size_t lseed;
 
130
  const char *seed;
 
131
  int lblock;
 
132
  char block[BLOCKSIZE+MAXKEY];
 
133
  checkseed(L);
 
134
  seed = luaL_checklstring(L, 3, &lseed);
 
135
  if (lseed > BLOCKSIZE)
 
136
    luaL_error(L, "seed too long (> %d)", BLOCKSIZE);
 
137
  /* put seed and seed length at the beginning of result */
 
138
  block[0] = (char)lseed;
 
139
  memcpy(block+1, seed, lseed);
 
140
  lua_pushlstring(L, block, lseed+1);  /* to concat with result */
 
141
  lblock = initblock(L, seed, lseed, block);
 
142
  codestream(L, msg, lmsg, block, lblock);
 
143
  lua_concat(L, 2);
 
144
  return 1;
 
145
}
 
146
 
 
147
 
 
148
/**
 
149
*  Decrypts a string. For any message, key, and seed, we have that
 
150
*  <code>decrypt(crypt(msg, key, seed), key) == msg</code>.
 
151
*  @param cyphertext: message to be decrypted (this must be the result of
 
152
   a previous call to <code>crypt</code>.
 
153
*  @param key: arbitrary binary string to be used as a key.
 
154
*  @return  The plaintext.
 
155
*/
 
156
static int decrypt (lua_State *L) {
 
157
  size_t lcyphertext;
 
158
  const char *cyphertext = luaL_checklstring(L, 1, &lcyphertext);
 
159
  size_t lseed = cyphertext[0];
 
160
  const char *seed = cyphertext+1;
 
161
  int lblock;
 
162
  char block[BLOCKSIZE+MAXKEY];
 
163
  luaL_argcheck(L, lcyphertext >= lseed+1 && lseed <= BLOCKSIZE, 1,
 
164
                 "invalid cyphered string");
 
165
  cyphertext += lseed+1;
 
166
  lcyphertext -= lseed+1;
 
167
  lblock = initblock(L, seed, lseed, block);
 
168
  decodestream(L, cyphertext, lcyphertext, block, lblock);
 
169
  return 1;
 
170
}
 
171
 
 
172
 
 
173
/*
 
174
** Assumes the table is on top of the stack.
 
175
*/
 
176
static void set_info (lua_State *L) {
 
177
        lua_pushliteral (L, "_COPYRIGHT");
 
178
        lua_pushliteral (L, "Copyright (C) 2003 PUC-Rio");
 
179
        lua_settable (L, -3);
 
180
        lua_pushliteral (L, "_DESCRIPTION");
 
181
        lua_pushliteral (L, "Basic cryptographic facilities");
 
182
        lua_settable (L, -3);
 
183
        lua_pushliteral (L, "_VERSION");
 
184
        lua_pushliteral (L, "MD5 1.1.2");
 
185
        lua_settable (L, -3);
 
186
}
 
187
 
 
188
 
 
189
static struct luaL_reg md5lib[] = {
 
190
  {"sum", lmd5},
 
191
  {"exor", ex_or},
 
192
  {"crypt", crypt},
 
193
  {"decrypt", decrypt},
 
194
  {NULL, NULL}
 
195
};
 
196
 
 
197
 
 
198
int luaopen_md5_core (lua_State *L) {
 
199
  luaL_openlib(L, "md5.core", md5lib, 0);
 
200
  set_info (L);
 
201
  return 1;
 
202
}
 
203