~ubuntu-branches/ubuntu/trusty/erlang/trusty

« back to all changes in this revision

Viewing changes to lib/crypto/c_src/crypto_drv.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum
  • Date: 2011-05-05 15:48:43 UTC
  • mfrom: (3.5.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110505154843-0om6ekzg6m7ugj27
Tags: 1:14.b.2-dfsg-3ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to.
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
  - debian/patches/series: Do what I meant, and enable build-options.patch
    instead.
* Additional changes:
  - Drop erlang-wx from -et
* Dropped Changes:
  - patches/pcre-crash.patch: CVE-2008-2371: outer level option with
    alternatives caused crash. (Applied Upstream)
  - fix for ssl certificate verification in newSSL: 
    ssl_cacertfile_fix.patch (Applied Upstream)
  - debian/patches/series: Enable native.patch again, to get stripped beam
    files and reduce the package size again. (build-options is what
    actually accomplished this)
  - Remove build-options.patch on advice from upstream and because it caused
    odd build failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * %CopyrightBegin%
3
 
 * 
4
 
 * Copyright Ericsson AB 1999-2009. All Rights Reserved.
5
 
 * 
6
 
 * The contents of this file are subject to the Erlang Public License,
7
 
 * Version 1.1, (the "License"); you may not use this file except in
8
 
 * compliance with the License. You should have received a copy of the
9
 
 * Erlang Public License along with this software. If not, it can be
10
 
 * retrieved online at http://www.erlang.org/.
11
 
 * 
12
 
 * Software distributed under the License is distributed on an "AS IS"
13
 
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
 
 * the License for the specific language governing rights and limitations
15
 
 * under the License.
16
 
 * 
17
 
 * %CopyrightEnd%
18
 
 */
19
 
 
20
 
/*
21
 
 * Purpose:  Dynamically loadable driver for cryptography libraries. 
22
 
 * Based on OpenSSL. 
23
 
 */
24
 
 
25
 
#ifdef __WIN32__
26
 
#include <windows.h>
27
 
#endif
28
 
 
29
 
#include <stdlib.h>
30
 
#include <stdio.h>
31
 
#include <string.h>
32
 
#include "erl_driver.h"
33
 
 
34
 
#define OPENSSL_THREAD_DEFINES
35
 
#include <openssl/opensslconf.h>
36
 
#ifndef OPENSSL_THREADS
37
 
#  ifdef __GNUC__
38
 
#    warning No thread support by openssl. Driver will use coarse grain locking.
39
 
#  endif 
40
 
#endif
41
 
 
42
 
#include <openssl/crypto.h>
43
 
#include <openssl/des.h>
44
 
/* #include <openssl/idea.h> This is not supported on the openssl OTP requires */
45
 
#include <openssl/dsa.h>
46
 
#include <openssl/rsa.h>
47
 
#include <openssl/aes.h>
48
 
#include <openssl/md5.h>
49
 
#include <openssl/md4.h>
50
 
#include <openssl/sha.h>
51
 
#include <openssl/bn.h>
52
 
#include <openssl/objects.h>
53
 
#include <openssl/rc4.h>
54
 
#include <openssl/rc2.h>
55
 
#include <openssl/blowfish.h>
56
 
#include <openssl/rand.h>
57
 
 
58
 
#ifdef VALGRIND
59
 
#  include <valgrind/memcheck.h>
60
 
 
61
 
/* libcrypto mixes supplied buffer contents into its entropy pool,
62
 
   which makes valgrind complain about the use of uninitialized data.
63
 
   We use this valgrind "request" to make sure that no such seemingly
64
 
   undefined data escapes the driver.
65
 
*/
66
 
#  define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size) \
67
 
    VALGRIND_MAKE_MEM_DEFINED(ptr,size)
68
 
 
69
 
#  define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size) \
70
 
    ((void) ((VALGRIND_CHECK_MEM_IS_DEFINED(ptr,size) == 0) ? 1 : \
71
 
    (fprintf(stderr,"\r\n####### VALGRIND_ASSSERT(%p,%d) failed at %s:%d\r\n",\
72
 
        (ptr),(size), __FILE__, __LINE__), abort(), 0)))
73
 
#else
74
 
#  define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size)
75
 
#  define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size)
76
 
#endif
77
 
 
78
 
#ifdef DEBUG
79
 
#  define ASSERT(e) \
80
 
    ((void) ((e) ? 1 : (fprintf(stderr,"Assert '%s' failed at %s:%d\n",\
81
 
                                #e, __FILE__, __LINE__), abort(), 0)))
82
 
#else
83
 
#  define ASSERT(e) ((void) 1)
84
 
#endif
85
 
 
86
 
#ifdef __GNUC__
87
 
#  define INLINE __inline__
88
 
#elif defined(__WIN32__)
89
 
#  define INLINE __forceinline
90
 
#else
91
 
#  define INLINE
92
 
#endif
93
 
 
94
 
 
95
 
#define get_int32(s) ((((unsigned char*) (s))[0] << 24) | \
96
 
                      (((unsigned char*) (s))[1] << 16) | \
97
 
                      (((unsigned char*) (s))[2] << 8)  | \
98
 
                      (((unsigned char*) (s))[3]))
99
 
 
100
 
#define put_int32(s,i) \
101
 
{ (s)[0] = (char)(((i) >> 24) & 0xff);\
102
 
  (s)[1] = (char)(((i) >> 16) & 0xff);\
103
 
  (s)[2] = (char)(((i) >> 8) & 0xff);\
104
 
  (s)[3] = (char)((i) & 0xff);\
105
 
}
106
 
 
107
 
/* Driver interface declarations */
108
 
static int init(void);
109
 
static void finish(void);
110
 
static ErlDrvData start(ErlDrvPort port, char *command);
111
 
static void stop(ErlDrvData drv_data);
112
 
static int crypto_control(ErlDrvData drv_data, unsigned int command, char *buf, 
113
 
                   int len, char **rbuf, int rlen); 
114
 
 
115
 
/* openssl callbacks */
116
 
#ifdef OPENSSL_THREADS
117
 
static void locking_function(int mode, int n, const char *file, int line);
118
 
static unsigned long id_function(void);
119
 
static struct CRYPTO_dynlock_value* dyn_create_function(const char *file,
120
 
                                                        int line);
121
 
static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value* ptr,
122
 
                              const char *file, int line);
123
 
static void dyn_destroy_function(struct CRYPTO_dynlock_value *ptr,
124
 
                                 const char *file, int line);
125
 
#endif /* OPENSSL_THREADS */
126
 
 
127
 
/* helpers */
128
 
static void hmac_md5(char *key, int klen, char *dbuf, int dlen, 
129
 
                     char *hmacbuf);
130
 
static void hmac_sha1(char *key, int klen, char *dbuf, int dlen, 
131
 
                      char *hmacbuf);
132
 
 
133
 
static ErlDrvEntry crypto_driver_entry = {
134
 
    init,
135
 
    start, 
136
 
    stop, 
137
 
    NULL,                       /* output */
138
 
    NULL,                       /* ready_input */
139
 
    NULL,                       /* ready_output */ 
140
 
    "crypto_drv", 
141
 
    finish,
142
 
    NULL,                       /* handle */
143
 
    crypto_control, 
144
 
    NULL,                       /* timeout */
145
 
    NULL,                       /* outputv */
146
 
 
147
 
    NULL,                       /* ready_async */
148
 
    NULL,                       /* flush */
149
 
    NULL,                       /* call */
150
 
    NULL,                       /* event */
151
 
    ERL_DRV_EXTENDED_MARKER,
152
 
    ERL_DRV_EXTENDED_MAJOR_VERSION,
153
 
    ERL_DRV_EXTENDED_MINOR_VERSION,
154
 
#ifdef OPENSSL_THREADS
155
 
    ERL_DRV_FLAG_USE_PORT_LOCKING,
156
 
#else
157
 
    0,
158
 
#endif
159
 
    NULL,                       /* handle2 */
160
 
    NULL                        /* process_exit */
161
 
};
162
 
 
163
 
 
164
 
/* Keep the following definitions in alignment with the FUNC_LIST
165
 
 * in crypto.erl. 
166
 
 */
167
 
 
168
 
#define DRV_INFO                0
169
 
#define DRV_MD5                 1
170
 
#define DRV_MD5_INIT            2
171
 
#define DRV_MD5_UPDATE          3
172
 
#define DRV_MD5_FINAL           4
173
 
#define DRV_SHA                 5
174
 
#define DRV_SHA_INIT            6
175
 
#define DRV_SHA_UPDATE          7
176
 
#define DRV_SHA_FINAL           8
177
 
#define DRV_MD5_MAC             9
178
 
#define DRV_MD5_MAC_96          10
179
 
#define DRV_SHA_MAC             11
180
 
#define DRV_SHA_MAC_96          12
181
 
#define DRV_CBC_DES_ENCRYPT     13
182
 
#define DRV_CBC_DES_DECRYPT     14
183
 
#define DRV_EDE3_CBC_DES_ENCRYPT 15
184
 
#define DRV_EDE3_CBC_DES_DECRYPT 16
185
 
#define DRV_AES_CFB_128_ENCRYPT 17
186
 
#define DRV_AES_CFB_128_DECRYPT 18
187
 
#define DRV_RAND_BYTES          19
188
 
#define DRV_RAND_UNIFORM        20
189
 
#define DRV_MOD_EXP             21
190
 
#define DRV_DSS_VERIFY          22
191
 
#define DRV_RSA_VERIFY_SHA      23
192
 
/* #define DRV_RSA_VERIFY_MD5      35 */ 
193
 
#define DRV_CBC_AES128_ENCRYPT  24
194
 
#define DRV_CBC_AES128_DECRYPT  25
195
 
#define DRV_XOR                 26
196
 
#define DRV_RC4_ENCRYPT         27 /* no decrypt needed; symmetric */
197
 
#define DRV_RC4_SETKEY          28
198
 
#define DRV_RC4_ENCRYPT_WITH_STATE 29
199
 
#define DRV_CBC_RC2_40_ENCRYPT     30
200
 
#define DRV_CBC_RC2_40_DECRYPT     31
201
 
#define DRV_CBC_AES256_ENCRYPT  32
202
 
#define DRV_CBC_AES256_DECRYPT  33
203
 
#define DRV_INFO_LIB            34
204
 
/* #define DRV_RSA_VERIFY_SHA      23 */
205
 
#define DRV_RSA_VERIFY_MD5      35 
206
 
#define DRV_RSA_SIGN_SHA        36
207
 
#define DRV_RSA_SIGN_MD5        37
208
 
#define DRV_DSS_SIGN            38
209
 
#define DRV_RSA_PUBLIC_ENCRYPT  39
210
 
#define DRV_RSA_PRIVATE_DECRYPT 40
211
 
#define DRV_RSA_PRIVATE_ENCRYPT 41
212
 
#define DRV_RSA_PUBLIC_DECRYPT  42
213
 
#define DRV_DH_GENERATE_PARAMS  43
214
 
#define DRV_DH_CHECK            44
215
 
#define DRV_DH_GENERATE_KEY     45
216
 
#define DRV_DH_COMPUTE_KEY      46
217
 
#define DRV_MD4                 47
218
 
#define DRV_MD4_INIT            48
219
 
#define DRV_MD4_UPDATE          49
220
 
#define DRV_MD4_FINAL           50
221
 
 
222
 
#define SSL_VERSION_0_9_8 0
223
 
#if SSL_VERSION_0_9_8
224
 
#define DRV_SHA256              51
225
 
#define DRV_SHA256_INIT         52
226
 
#define DRV_SHA256_UPDATE       53
227
 
#define DRV_SHA256_FINAL        54
228
 
#define DRV_SHA512              55
229
 
#define DRV_SHA512_INIT         56
230
 
#define DRV_SHA512_UPDATE       57
231
 
#define DRV_SHA512_FINAL        58
232
 
#endif
233
 
 
234
 
#define DRV_BF_CFB64_ENCRYPT     59
235
 
#define DRV_BF_CFB64_DECRYPT     60
236
 
 
237
 
/* #define DRV_CBC_IDEA_ENCRYPT    34 */
238
 
/* #define DRV_CBC_IDEA_DECRYPT    35 */
239
 
 
240
 
/* Not DRV_DH_GENERATE_PARAMS DRV_DH_CHECK
241
 
 * Calc RSA_VERIFY_*  and RSA_SIGN once */
242
 
#define NUM_CRYPTO_FUNCS        46
243
 
 
244
 
#define MD5_CTX_LEN     (sizeof(MD5_CTX))
245
 
#define MD5_LEN         16
246
 
#define MD5_LEN_96      12
247
 
#define MD4_CTX_LEN     (sizeof(MD4_CTX))
248
 
#define MD4_LEN         16
249
 
#define SHA_CTX_LEN     (sizeof(SHA_CTX))
250
 
#define SHA_LEN         20
251
 
#define SHA_LEN_96      12
252
 
#define HMAC_INT_LEN    64
253
 
 
254
 
#define HMAC_IPAD       0x36
255
 
#define HMAC_OPAD       0x5c
256
 
 
257
 
#if SSL_VERSION_0_9_8
258
 
#define SHA256_CTX_LEN (sizeof(SHA256_CTX))
259
 
#define SHA256_LEN     32
260
 
 
261
 
#define SHA512_CTX_LEN (sizeof(SHA512_CTX))
262
 
#define SHA512_LEN     64
263
 
#endif
264
 
 
265
 
/* INITIALIZATION AFTER LOADING */
266
 
 
267
 
/* 
268
 
 * This is the init function called after this driver has been loaded.
269
 
 * It must *not* be declared static. Must return the address to 
270
 
 * the driver entry.
271
 
 */
272
 
 
273
 
#if !defined(__WIN32__)
274
 
DRIVER_INIT(crypto_drv);
275
 
#endif
276
 
 
277
 
DRIVER_INIT(crypto_drv)
278
 
{
279
 
    return &crypto_driver_entry;
280
 
}
281
 
 
282
 
static ErlDrvRWLock** lock_vec = NULL; /* Static locks used by openssl */
283
 
 
284
 
/* DRIVER INTERFACE */
285
 
 
286
 
static int init(void)
287
 
{
288
 
    ErlDrvSysInfo sys_info;
289
 
    int i;
290
 
 
291
 
    CRYPTO_set_mem_functions(driver_alloc, driver_realloc, driver_free);
292
 
 
293
 
#ifdef OPENSSL_THREADS
294
 
    driver_system_info(&sys_info, sizeof(sys_info));
295
 
 
296
 
    if(sys_info.scheduler_threads > 1) {
297
 
        lock_vec = driver_alloc(CRYPTO_num_locks()*sizeof(*lock_vec));
298
 
        if (lock_vec==NULL) return -1;
299
 
        memset(lock_vec,0,CRYPTO_num_locks()*sizeof(*lock_vec));
300
 
    
301
 
        for(i=CRYPTO_num_locks()-1; i>=0; --i) {
302
 
            lock_vec[i] = erl_drv_rwlock_create("crypto_drv_stat");
303
 
            if (lock_vec[i]==NULL) return -1;
304
 
        }
305
 
        CRYPTO_set_locking_callback(locking_function);    
306
 
        CRYPTO_set_id_callback(id_function);
307
 
        CRYPTO_set_dynlock_create_callback(dyn_create_function);
308
 
        CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
309
 
        CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
310
 
    }
311
 
    /* else no need for locks */
312
 
#endif /* OPENSSL_THREADS */
313
 
 
314
 
    return 0;
315
 
}
316
 
 
317
 
static void finish(void)
318
 
{
319
 
    /* Moved here from crypto_control() as it's not thread safe */
320
 
    CRYPTO_cleanup_all_ex_data();
321
 
 
322
 
    if(lock_vec != NULL) {
323
 
        int i;
324
 
        for(i=CRYPTO_num_locks()-1; i>=0; --i) {
325
 
            if (lock_vec[i] != NULL) {
326
 
                erl_drv_rwlock_destroy(lock_vec[i]);
327
 
            }
328
 
        }
329
 
        driver_free(lock_vec);
330
 
    }
331
 
}
332
 
 
333
 
static ErlDrvData start(ErlDrvPort port, char *command)
334
 
335
 
    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
336
 
    return 0; /* not used */
337
 
}
338
 
 
339
 
static void stop(ErlDrvData drv_data)
340
 
{
341
 
    return;
342
 
}
343
 
 
344
 
/* Helper functions for 'crypto_control'
345
 
*/
346
 
static INLINE unsigned char* return_binary(char **rbuf, int rlen, int len)
347
 
{
348
 
    if (len <= rlen) {
349
 
        return (unsigned char *) *rbuf;
350
 
    }
351
 
    else {
352
 
        ErlDrvBinary* bin;
353
 
        *rbuf = (char*) (bin = driver_alloc_binary(len));       
354
 
        return (bin==NULL) ? NULL : (unsigned char *) bin->orig_bytes;
355
 
    }
356
 
}
357
 
 
358
 
static INLINE unsigned char* return_binary_shrink(char **rbuf, int rlen, unsigned char* data, int len)
359
 
{
360
 
    if ((char *) data == *rbuf) { /* default buffer */
361
 
        ASSERT(len <= rlen);
362
 
        return (unsigned char *) data;
363
 
    }
364
 
    else {
365
 
        ErlDrvBinary* bin = (ErlDrvBinary*) *rbuf;
366
 
        *rbuf = (char*) (bin=driver_realloc_binary(bin, len));
367
 
        return (bin==NULL) ? NULL : (unsigned char *) bin->orig_bytes;
368
 
    }
369
 
}
370
 
 
371
 
/* Nowadays (R13) it does matter what value control returns
372
 
 * as it may return data in default buffer.
373
 
 */
374
 
static int crypto_control(ErlDrvData drv_data, unsigned int command, char *buf, 
375
 
                          int len, char **rbuf, int rlen)
376
 
{
377
 
    int klen, dlen, macsize, from_len, to_len, i;
378
 
    int base_len, exponent_len, modulo_len;
379
 
    int data_len, dsa_p_len, dsa_q_len;
380
 
    int dsa_s_len, dsa_g_len, dsa_y_len;
381
 
    int rsa_e_len, rsa_n_len, rsa_d_len, padding;
382
 
    int or_mask;
383
 
    int prime_len, generator;
384
 
    int privkey_len, pubkey_len, dh_p_len, dh_g_len;
385
 
    unsigned int rsa_s_len, j;
386
 
    char *key, *key2, *dbuf;
387
 
    unsigned char *p;
388
 
    const_DES_cblock *des_key, *des_key2, *des_key3;
389
 
    const unsigned char *des_dbuf;
390
 
    BIGNUM *bn_from, *bn_to, *bn_rand, *bn_result;
391
 
    BIGNUM *bn_base, *bn_exponent, *bn_modulo;
392
 
    BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_y;
393
 
    BIGNUM *rsa_n, *rsa_e, *rsa_d;
394
 
    BIGNUM *dh_p, *dh_g, *privkey, *pubkey;
395
 
    DES_cblock *des_ivec;
396
 
    unsigned char* bin;
397
 
    DES_key_schedule schedule, schedule2, schedule3;
398
 
    DH *dh_params;
399
 
/*     IDEA_KEY_SCHEDULE idea, idea2; */
400
 
    char hmacbuf[SHA_DIGEST_LENGTH];
401
 
    unsigned char *rsa_s, *dsa_s;   
402
 
    /* char hmacbuf[SHA_LEN]; */
403
 
#if SSL_VERSION_0_9_8
404
 
    SHA256_CTX sha256_ctx;
405
 
    SHA512_CTX sha512_ctx;
406
 
#endif
407
 
    MD5_CTX md5_ctx;
408
 
    MD4_CTX md4_ctx;
409
 
    SHA_CTX sha_ctx;
410
 
    int new_ivlen = 0;
411
 
    BN_CTX *bn_ctx;
412
 
    DSA *dsa;
413
 
    RSA *rsa;
414
 
    AES_KEY aes_key;
415
 
    RC4_KEY rc4_key;
416
 
    RC2_KEY rc2_key;
417
 
 
418
 
    switch(command) {
419
 
 
420
 
    case DRV_INFO:
421
 
        bin = return_binary(rbuf,rlen,NUM_CRYPTO_FUNCS);
422
 
        if (bin==NULL) return -1;
423
 
 
424
 
        for (i = 0; i < NUM_CRYPTO_FUNCS; i++) {
425
 
            bin[i] = i + 1;
426
 
        }
427
 
        return NUM_CRYPTO_FUNCS;
428
 
 
429
 
    case DRV_MD5:
430
 
        bin = return_binary(rbuf,rlen,MD5_LEN); 
431
 
       if (bin==NULL) return -1;
432
 
        MD5((unsigned char *) buf, len, bin);
433
 
        return MD5_LEN;
434
 
 
435
 
    case DRV_MD5_INIT:
436
 
        bin = return_binary(rbuf,rlen,MD5_CTX_LEN);
437
 
        if (bin==NULL) return -1;
438
 
        MD5_Init((MD5_CTX *)bin);
439
 
        return MD5_CTX_LEN;             
440
 
 
441
 
    case DRV_MD5_UPDATE:
442
 
        if (len < MD5_CTX_LEN)
443
 
            return -1;
444
 
        bin = return_binary(rbuf,rlen,MD5_CTX_LEN);
445
 
        if (bin==NULL) return -1;
446
 
        memcpy(bin, buf, MD5_CTX_LEN);
447
 
        MD5_Update((MD5_CTX *)bin, buf + MD5_CTX_LEN, 
448
 
                   len - MD5_CTX_LEN);
449
 
        return MD5_CTX_LEN;             
450
 
 
451
 
    case DRV_MD5_FINAL:
452
 
        if (len != MD5_CTX_LEN)
453
 
            return -1;
454
 
        memcpy(&md5_ctx, buf, MD5_CTX_LEN); /* XXX Use buf only? */
455
 
        bin = return_binary(rbuf,rlen,MD5_LEN);
456
 
        if (bin==NULL) return -1;       
457
 
        MD5_Final(bin, &md5_ctx);
458
 
        return MD5_LEN;         
459
 
 
460
 
    case DRV_SHA:
461
 
        bin = return_binary(rbuf,rlen,SHA_LEN);
462
 
        if (bin==NULL) return -1;
463
 
        SHA1((unsigned char *) buf, len, bin);
464
 
        return SHA_LEN;
465
 
 
466
 
    case DRV_SHA_INIT:
467
 
        bin = return_binary(rbuf,rlen,SHA_CTX_LEN);
468
 
        if (bin==NULL) return -1;
469
 
        SHA1_Init((SHA_CTX*)bin);
470
 
        return SHA_CTX_LEN;             
471
 
 
472
 
    case DRV_SHA_UPDATE:
473
 
        if (len < SHA_CTX_LEN)
474
 
            return -1;
475
 
        bin = return_binary(rbuf,rlen,SHA_CTX_LEN);
476
 
        if (bin==NULL) return -1;
477
 
        memcpy(bin, buf, SHA_CTX_LEN);
478
 
        SHA1_Update((SHA_CTX*)bin, buf + SHA_CTX_LEN, len - SHA_CTX_LEN);
479
 
        return SHA_CTX_LEN;             
480
 
 
481
 
    case DRV_SHA_FINAL:
482
 
        if (len != SHA_CTX_LEN)
483
 
            return -1;
484
 
        memcpy(&sha_ctx, buf, SHA_CTX_LEN); /* XXX Use buf only? */
485
 
        bin = return_binary(rbuf,rlen,SHA_LEN);
486
 
        if (bin==NULL) return -1;
487
 
        SHA1_Final(bin, &sha_ctx);
488
 
        return SHA_LEN;         
489
 
 
490
 
    case DRV_MD5_MAC:
491
 
    case DRV_MD5_MAC_96:
492
 
        /* buf = klen[4] key data */
493
 
        klen = get_int32(buf);
494
 
        key = buf + 4;
495
 
        dlen = len - klen - 4;
496
 
        dbuf = key + klen;
497
 
        hmac_md5(key, klen, dbuf, dlen, hmacbuf);
498
 
        macsize = (command == DRV_MD5_MAC) ? MD5_LEN : MD5_LEN_96;
499
 
        bin = return_binary(rbuf,rlen,macsize);
500
 
        if (bin==NULL) return -1;
501
 
        memcpy(bin, hmacbuf, macsize);
502
 
        return macsize;
503
 
 
504
 
    case DRV_SHA_MAC:
505
 
    case DRV_SHA_MAC_96:
506
 
        /* buf = klen[4] key data */
507
 
        klen = get_int32(buf);
508
 
        key = buf + 4;
509
 
        dlen = len - klen - 4;
510
 
        dbuf = key + klen;
511
 
        hmac_sha1(key, klen, dbuf, dlen, hmacbuf);
512
 
        macsize = (command == DRV_SHA_MAC) ? SHA_LEN : SHA_LEN_96;
513
 
        bin = return_binary(rbuf,rlen,macsize);
514
 
        if (bin==NULL) return -1;
515
 
        memcpy(bin, (unsigned char *) hmacbuf, macsize);
516
 
        return macsize;
517
 
 
518
 
    case DRV_CBC_DES_ENCRYPT:
519
 
    case DRV_CBC_DES_DECRYPT:
520
 
        /* buf = key[8] ivec[8] data */
521
 
        dlen = len - 16;
522
 
        if (dlen < 0)
523
 
            return -1;
524
 
        if (dlen % 8 != 0)
525
 
            return -1;
526
 
        des_key = (const_DES_cblock*) buf; 
527
 
        des_ivec = (DES_cblock*)(buf + 8); 
528
 
        des_dbuf = (unsigned char *) (buf + 16);
529
 
        bin = return_binary(rbuf,rlen,dlen);
530
 
        if (bin==NULL) return -1;
531
 
        DES_set_key(des_key, &schedule);
532
 
        DES_ncbc_encrypt(des_dbuf, bin, dlen, &schedule, des_ivec, 
533
 
                         (command == DRV_CBC_DES_ENCRYPT));
534
 
        return dlen;
535
 
 
536
 
    case DRV_BF_CFB64_ENCRYPT:
537
 
    case DRV_BF_CFB64_DECRYPT:
538
 
    {
539
 
        /* buf = klen[4] key ivec[8] data */
540
 
        unsigned char* ivec;
541
 
        unsigned char bf_tkey[8]; /* blowfish ivec */    
542
 
        int bf_n; /* blowfish ivec pos */    
543
 
        int bf_direction;
544
 
        const unsigned char *bf_dbuf; /* blowfish input data */   
545
 
        BF_KEY bf_key; /* blowfish key 8 */
546
 
        
547
 
        klen = get_int32(buf);
548
 
        key = buf + 4;
549
 
        ivec = (unsigned char *) (key + klen);
550
 
        bf_dbuf = ivec + 8;
551
 
        dlen = len - 4 - klen - 8;
552
 
        if (dlen < 0) return -1;
553
 
        BF_set_key(&bf_key, klen, (unsigned char *) key);
554
 
        memcpy(bf_tkey, ivec, 8);
555
 
        bin = return_binary(rbuf,rlen,dlen);
556
 
        if (bin==NULL) return -1;
557
 
        bf_direction = command == DRV_BF_CFB64_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT;
558
 
        bf_n = 0;
559
 
        BF_cfb64_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, &bf_n, bf_direction);
560
 
        return dlen;
561
 
    }
562
 
 
563
 
/*     case DRV_CBC_IDEA_ENCRYPT: */
564
 
/*     case DRV_CBC_IDEA_DECRYPT: */
565
 
         /* buf = key[16] ivec[8] data */
566
 
/*         dlen = len - 24; */
567
 
/*         if (dlen < 0) */
568
 
/*             return -1; */
569
 
/*      if (dlen % 8 != 0) */
570
 
/*          return -1; */
571
 
/*         bin = return_binary(rbuf,rlen,dlen); */
572
 
/*         idea_set_encrypt_key(buf, &idea); */
573
 
/*      if (command == DRV_CBC_IDEA_DECRYPT) { */
574
 
/*          idea_set_decrypt_key(&idea, &idea2); */
575
 
/*          memcpy(&idea, &idea2, sizeof(idea));  */
576
 
/*      } */
577
 
/*         idea_cbc_encrypt(buf + 24, bin, dlen, &idea, buf + 8, */
578
 
/*                          (command == DRV_CBC_IDEA_ENCRYPT)); */
579
 
/*         return dlen; */
580
 
 
581
 
    case DRV_CBC_RC2_40_ENCRYPT:
582
 
    case DRV_CBC_RC2_40_DECRYPT:
583
 
        /* buf = key[5] ivec[8] data */
584
 
        dlen = len - 13;
585
 
        if (dlen < 0)
586
 
            return -1;
587
 
        bin = return_binary(rbuf,rlen,dlen);
588
 
        if (bin==NULL) return -1;
589
 
        RC2_set_key(&rc2_key, 5, (unsigned char *) buf, 40);
590
 
        RC2_cbc_encrypt((unsigned char *) (buf + 13), bin, dlen, &rc2_key, 
591
 
                        (unsigned char *) (buf + 5),
592
 
                        (command == DRV_CBC_RC2_40_ENCRYPT));
593
 
        return dlen;
594
 
 
595
 
    case DRV_EDE3_CBC_DES_ENCRYPT:
596
 
    case DRV_EDE3_CBC_DES_DECRYPT:
597
 
        dlen = len - 32;
598
 
        if (dlen < 0)
599
 
            return -1;
600
 
        des_key = (const_DES_cblock*) buf; 
601
 
        des_key2 = (const_DES_cblock*) (buf + 8); 
602
 
        des_key3 = (const_DES_cblock*) (buf + 16);
603
 
        des_ivec = (DES_cblock*) (buf + 24); 
604
 
        des_dbuf = (unsigned char *) (buf + 32);
605
 
        bin = return_binary(rbuf,rlen,dlen);
606
 
        if (bin==NULL) return -1;
607
 
        DES_set_key(des_key, &schedule);
608
 
        DES_set_key(des_key2, &schedule2);
609
 
        DES_set_key(des_key3, &schedule3);
610
 
        DES_ede3_cbc_encrypt(des_dbuf, bin, dlen, &schedule,
611
 
                             &schedule2, &schedule3, des_ivec, 
612
 
                             (command == DRV_EDE3_CBC_DES_ENCRYPT));
613
 
        return dlen;
614
 
 
615
 
    case DRV_AES_CFB_128_ENCRYPT:
616
 
    case DRV_AES_CFB_128_DECRYPT:
617
 
        /* buf = key[16] ivec[16] data */
618
 
        dlen = len - 32;
619
 
        if (dlen < 0)
620
 
            return -1;
621
 
        bin = return_binary(rbuf,rlen,dlen);
622
 
        if (bin==NULL) return -1;
623
 
        AES_set_encrypt_key((unsigned char *) buf, 128, &aes_key);
624
 
        AES_cfb128_encrypt((unsigned char *) (buf+32), bin, dlen, &aes_key,
625
 
                           (unsigned char *) (buf+16), &new_ivlen,
626
 
                           (command == DRV_AES_CFB_128_ENCRYPT));
627
 
        return dlen;
628
 
 
629
 
    case DRV_RC4_ENCRYPT:
630
 
        /* buf = klen[4] key data */
631
 
        klen = get_int32(buf);
632
 
        key = buf + 4;
633
 
        dlen = len - klen - 4;
634
 
        dbuf = key + klen;
635
 
        bin = return_binary(rbuf,rlen,dlen);
636
 
        if (bin==NULL) return -1;
637
 
        RC4_set_key(&rc4_key, klen, (unsigned char *) key);
638
 
        RC4(&rc4_key, dlen, (unsigned char *) dbuf, bin);
639
 
        return dlen;
640
 
 
641
 
    case DRV_RC4_SETKEY:
642
 
        /* buf = key */
643
 
        dlen = sizeof(rc4_key);
644
 
        bin = return_binary(rbuf,rlen,dlen);
645
 
        if (bin==NULL) return -1;
646
 
        RC4_set_key(&rc4_key, len, (unsigned char *) buf);
647
 
        memcpy(bin, &rc4_key, dlen);
648
 
        return dlen;
649
 
 
650
 
    case DRV_RC4_ENCRYPT_WITH_STATE:
651
 
        /* buf = statelength[4] state data, return statelength[4] state data */
652
 
        klen = get_int32(buf);
653
 
        key = buf + 4;
654
 
        dlen = len - klen - 4;
655
 
        dbuf = key + klen;
656
 
        bin = return_binary(rbuf,rlen,len);
657
 
        if (bin==NULL) return -1;
658
 
        memcpy(&rc4_key, key, klen);
659
 
        RC4(&rc4_key, dlen, (unsigned char *) dbuf, bin + klen + 4);
660
 
        memcpy(bin, buf, 4);
661
 
        memcpy(bin + 4, &rc4_key, klen);
662
 
        return len;
663
 
 
664
 
    case DRV_RAND_BYTES:
665
 
        /* buf = <<rlen:32/integer,topmask:8/integer,bottommask:8/integer>> */
666
 
 
667
 
        if (len != 6)
668
 
            return -1;
669
 
        dlen = get_int32(buf);
670
 
        bin = return_binary(rbuf,rlen,dlen);
671
 
        if (bin==NULL) return -1;
672
 
        RAND_pseudo_bytes(bin,dlen);
673
 
        ERL_VALGRIND_MAKE_MEM_DEFINED(bin, dlen);
674
 
        or_mask = ((unsigned char*)buf)[4];
675
 
        bin[dlen-1] |= or_mask; /* topmask */
676
 
        or_mask = ((unsigned char*)buf)[5];
677
 
        bin[0] |= or_mask; /* bottommask */
678
 
        return dlen;
679
 
      
680
 
    case DRV_RAND_UNIFORM:
681
 
      /* buf = <<from_len:32/integer,bn_from:from_len/binary,   *
682
 
       *         to_len:32/integer,bn_to:to_len/binary>>        */
683
 
      if (len < 8)
684
 
        return -1;
685
 
      from_len = get_int32(buf);
686
 
      if (len < (8 + from_len))
687
 
        return -1;
688
 
      to_len = get_int32(buf + 4 + from_len);
689
 
      if (len != (8 + from_len + to_len))
690
 
        return -1;
691
 
      ERL_VALGRIND_ASSERT_MEM_DEFINED(buf, 4 + from_len + 4 + to_len);
692
 
      bn_from = BN_new();
693
 
      BN_bin2bn((unsigned char *)(buf + 4), from_len, bn_from);
694
 
      bn_rand = BN_new();
695
 
      BN_bin2bn((unsigned char *)(buf + 8 + from_len), to_len, bn_rand);
696
 
      bn_to = BN_new();
697
 
      BN_sub(bn_to, bn_rand, bn_from);
698
 
      BN_pseudo_rand_range(bn_rand, bn_to);      
699
 
      BN_add(bn_rand, bn_rand, bn_from);
700
 
      dlen = BN_num_bytes(bn_rand);
701
 
      bin = return_binary(rbuf,rlen,dlen + 4);
702
 
      if (bin==NULL) return -1;
703
 
      put_int32(bin, dlen);
704
 
      BN_bn2bin(bn_rand,(unsigned char*)(bin + 4));
705
 
      ERL_VALGRIND_MAKE_MEM_DEFINED(bin+4, dlen);
706
 
      BN_free(bn_rand);
707
 
      BN_free(bn_from);
708
 
      BN_free(bn_to);
709
 
      return dlen + 4;
710
 
      
711
 
    case DRV_MOD_EXP:
712
 
      /* buf = <<base_len:32/integer,base/binary,          *
713
 
       *         exponent_len:32/integer,exponent/binary,  *
714
 
       *         modulo_len:32/integer, modulo/binary>>    */
715
 
      if (len < 12)
716
 
        return -1;
717
 
      base_len = get_int32(buf);
718
 
      if (len < (12 + base_len))
719
 
        return -1;
720
 
      exponent_len = get_int32(buf + 4 + base_len);
721
 
      if (len < (12 + base_len + exponent_len))
722
 
        return -1;
723
 
      modulo_len = get_int32(buf + 8 + base_len + exponent_len);
724
 
      if (len != (12 + base_len + exponent_len + modulo_len))
725
 
        return -1;
726
 
      bn_base = BN_new();
727
 
      BN_bin2bn((unsigned char *)(buf + 4),
728
 
                base_len, bn_base);
729
 
      bn_exponent = BN_new();
730
 
      BN_bin2bn((unsigned char *)(buf + 8 + base_len),
731
 
                exponent_len, bn_exponent);
732
 
      bn_modulo = BN_new();
733
 
      BN_bin2bn((unsigned char *)(buf + 12 + base_len + exponent_len),
734
 
                modulo_len, bn_modulo);
735
 
      bn_result = BN_new();
736
 
      bn_ctx = BN_CTX_new();
737
 
      BN_mod_exp(bn_result, bn_base, bn_exponent,
738
 
                 bn_modulo, bn_ctx);
739
 
      dlen = BN_num_bytes(bn_result);
740
 
      bin = return_binary(rbuf,rlen,dlen + 4);
741
 
      if (bin==NULL) return -1;
742
 
      put_int32(bin, dlen);
743
 
      BN_bn2bin(bn_result,(unsigned char*)(bin + 4));
744
 
      BN_free(bn_result);
745
 
      BN_free(bn_modulo);
746
 
      BN_free(bn_exponent);
747
 
      BN_free(bn_base);
748
 
      BN_CTX_free(bn_ctx);
749
 
      return dlen + 4;
750
 
 
751
 
    case DRV_DSS_VERIFY:
752
 
      /* buf = <<data_len:32/integer, data:data_len/binary,
753
 
       *         dsa_s_len:32/integer, dsa_s:dsa_s_len/binary,
754
 
       *         dsa_p_len:32/integer, dsa_p:dsa_p_len/binary,
755
 
       *         dsa_q_len:32/integer, dsa_q:dsa_q_len/binary,
756
 
       *         dsa_g_len:32/integer, dsa_g:dsa_g_len/binary,
757
 
       *         dsa_y_len:32/integer, dsa_y:dsa_y_len/binary>> */
758
 
      i = 0;
759
 
      j = 0;
760
 
      if (len < 24)
761
 
        return -1;
762
 
      data_len = get_int32(buf + i + j);
763
 
      j += data_len; i += 4;
764
 
      if (len < (24 + j))
765
 
        return -1;
766
 
      dsa_s_len = get_int32(buf + i + j);
767
 
      j += dsa_s_len; i += 4;
768
 
      if (len < (24 + j))
769
 
         return -1;      
770
 
      dsa_p_len = get_int32(buf + i + j);
771
 
      j += dsa_p_len; i += 4;
772
 
      if (len < (24 + j))
773
 
        return -1;
774
 
      dsa_q_len = get_int32(buf + i + j);
775
 
      j += dsa_q_len; i += 4;
776
 
      if (len < (24 + j))
777
 
        return -1;
778
 
      dsa_g_len = get_int32(buf + i + j);
779
 
      j += dsa_g_len; i += 4;
780
 
      if (len < (24 + j))
781
 
        return -1;
782
 
      dsa_y_len = get_int32(buf + i + j);
783
 
      j += dsa_y_len;
784
 
      if (len != (24 + j))
785
 
        return -1;
786
 
      i = 4;
787
 
      SHA1((unsigned char *) (buf + i), data_len, (unsigned char *) hmacbuf);
788
 
      i += data_len + 4;
789
 
      dsa_s = (unsigned char *)(buf + i);
790
 
      i += (dsa_s_len + 4);
791
 
      dsa_p = BN_new();
792
 
      BN_bin2bn((unsigned char *)(buf + i), dsa_p_len, dsa_p);
793
 
      i += (dsa_p_len + 4);
794
 
      dsa_q = BN_new();
795
 
      BN_bin2bn((unsigned char *)(buf + i), dsa_q_len, dsa_q);
796
 
      i += (dsa_q_len + 4);
797
 
      dsa_g = BN_new();
798
 
      BN_bin2bn((unsigned char *)(buf + i), dsa_g_len, dsa_g);
799
 
      i += (dsa_g_len + 4);
800
 
      dsa_y = BN_new();
801
 
      BN_bin2bn((unsigned char *)(buf + i), dsa_y_len, dsa_y);
802
 
      dsa = DSA_new();
803
 
      dsa->p = dsa_p;
804
 
      dsa->q = dsa_q;
805
 
      dsa->g = dsa_g;
806
 
      dsa->priv_key = NULL;
807
 
      dsa->pub_key = dsa_y;
808
 
      i =  DSA_verify(0, (unsigned char *) hmacbuf, SHA_DIGEST_LENGTH, 
809
 
                      dsa_s, dsa_s_len, dsa);
810
 
      bin = return_binary(rbuf,rlen,1);
811
 
      if (bin==NULL) return -1;
812
 
 
813
 
      DSA_free(dsa);
814
 
      bin[0] = (i > 0) ? 1 : 0;
815
 
      return 1;
816
 
      
817
 
    case DRV_DSS_SIGN:
818
 
      /* buf = <<data_len:32/integer, data:data_len/binary,
819
 
       *         dsa_p_len:32/integer, dsa_p:dsa_p_len/binary,
820
 
       *         dsa_q_len:32/integer, dsa_q:dsa_q_len/binary,
821
 
       *         dsa_g_len:32/integer, dsa_g:dsa_g_len/binary,
822
 
       *         dsa_y_len:32/integer, dsa_y:dsa_y_len/binary,
823
 
       *         dsa_x_len:32/integer, dsa_s:dsa_x_len/binary>> */
824
 
      i = 0;
825
 
      j = 0;
826
 
      if (len < 20)
827
 
         return -1;
828
 
      data_len = get_int32(buf + i + j);
829
 
      j += data_len; i += 4;
830
 
      if (len < (20 + j))
831
 
          return -1;
832
 
      dsa_p_len = get_int32(buf + i + j);
833
 
      j += dsa_p_len; i += 4;
834
 
      if (len < (20 + j))
835
 
         return -1;
836
 
      dsa_q_len = get_int32(buf + i + j);
837
 
      j += dsa_q_len; i += 4;
838
 
      if (len < (20 + j))
839
 
         return -1;
840
 
      dsa_g_len = get_int32(buf + i + j);
841
 
      j += dsa_g_len; i += 4;
842
 
      if (len < (20 + j))
843
 
         return -1;
844
 
      dsa_y_len = get_int32(buf + i + j);
845
 
      j += dsa_y_len;
846
 
      if (len < (20 + j))
847
 
         return -1;
848
 
      if (len != (20 + j))
849
 
         return -1;
850
 
 
851
 
      i = 4;
852
 
      SHA1((unsigned char *) (buf + i), data_len, (unsigned char *) hmacbuf);
853
 
      i += data_len + 4;
854
 
      dsa_p = BN_new();
855
 
      BN_bin2bn((unsigned char *)(buf + i), dsa_p_len, dsa_p);
856
 
      i += (dsa_p_len + 4);
857
 
      dsa_q = BN_new();
858
 
      BN_bin2bn((unsigned char *)(buf + i), dsa_q_len, dsa_q);
859
 
      i += (dsa_q_len + 4);
860
 
      dsa_g = BN_new();
861
 
      BN_bin2bn((unsigned char *)(buf + i), dsa_g_len, dsa_g);
862
 
      i += (dsa_g_len + 4);
863
 
      dsa_y = BN_new();
864
 
      BN_bin2bn((unsigned char *)(buf + i), dsa_y_len, dsa_y);
865
 
      /* i += (dsa_y_len + 4); */
866
 
 
867
 
      dsa = DSA_new();
868
 
      dsa->p = dsa_p;
869
 
      dsa->q = dsa_q;
870
 
      dsa->g = dsa_g;
871
 
      dsa->priv_key = dsa_y;
872
 
      dsa->pub_key  = NULL;
873
 
      dlen = DSA_size(dsa);
874
 
      bin = return_binary(rbuf,rlen, dlen+1);
875
 
      if (bin==NULL) return -1;
876
 
      i =  DSA_sign(NID_sha1,
877
 
                    (unsigned char *) hmacbuf,SHA_DIGEST_LENGTH,
878
 
                    (unsigned char *) &bin[1],
879
 
                    (unsigned int *) &dsa_s_len, dsa);
880
 
      DSA_free(dsa);
881
 
      if (i) {
882
 
          if (dsa_s_len != dlen) {
883
 
              bin = return_binary_shrink(rbuf,rlen,bin,dsa_s_len+1);
884
 
          }
885
 
          bin[0] = 1;
886
 
          return dsa_s_len + 1;
887
 
      }
888
 
      else {
889
 
          bin[0] = 0;
890
 
          return 1;
891
 
      }
892
 
 
893
 
    case DRV_RSA_VERIFY_MD5:
894
 
    case DRV_RSA_VERIFY_SHA:
895
 
      /* buf = <<data_len:32/integer, data:data_len/binary,
896
 
       *         rsa_s_len:32/integer, rsa_s:rsa_s_len/binary,
897
 
       *         rsa_e_len:32/integer, rsa_e:rsa_e_len/binary,
898
 
       *         rsa_n_len:32/integer, rsa_n:rsa_n_len/binary>> */
899
 
      i = 0;
900
 
      j = 0;
901
 
      if (len < 16)
902
 
         return -1;
903
 
      data_len = get_int32(buf + i + j);
904
 
      j += data_len; i += 4;
905
 
      if (len < (16 + j))
906
 
        return -1;
907
 
      rsa_s_len = get_int32(buf + i + j);
908
 
      j += rsa_s_len; i += 4;
909
 
      if (len < (16 + j))
910
 
        return -1;
911
 
      rsa_e_len = get_int32(buf + i + j);
912
 
      j += rsa_e_len; i += 4;
913
 
      if (len < (16 + j))
914
 
        return -1;
915
 
      rsa_n_len = get_int32(buf + i + j);
916
 
      j += rsa_n_len; i += 4;
917
 
      if (len != (16 + j))
918
 
         return -1;
919
 
      i = 4;
920
 
      i += (data_len + 4);
921
 
      rsa_s = (unsigned char *)(buf + i);
922
 
      i += (rsa_s_len + 4);
923
 
      rsa_e = BN_new();
924
 
      BN_bin2bn((unsigned char *)(buf + i), rsa_e_len, rsa_e);
925
 
      i += (rsa_e_len + 4);
926
 
      rsa_n = BN_new();
927
 
      BN_bin2bn((unsigned char *)(buf + i), rsa_n_len, rsa_n);
928
 
      rsa = RSA_new();
929
 
      rsa->n = rsa_n;
930
 
      rsa->e = rsa_e;
931
 
      i = 4;
932
 
      if(command == DRV_RSA_VERIFY_SHA) {
933
 
         SHA1((unsigned char *) (buf + i), data_len, 
934
 
              (unsigned char *) hmacbuf);
935
 
         i = RSA_verify(NID_sha1, (unsigned char *) hmacbuf, SHA_DIGEST_LENGTH,
936
 
                        rsa_s, rsa_s_len, rsa);
937
 
      } else {
938
 
         MD5((unsigned char *) (buf + i), data_len, (unsigned char *) hmacbuf);
939
 
         i =  RSA_verify(NID_md5, (unsigned char *) hmacbuf, MD5_DIGEST_LENGTH,
940
 
                         rsa_s, rsa_s_len, rsa);
941
 
      }
942
 
 
943
 
      bin = return_binary(rbuf,rlen,1);
944
 
      if (bin==NULL) return -1;
945
 
      bin[0] = (char)(i & 0xff);
946
 
      RSA_free(rsa);
947
 
      return 1;
948
 
 
949
 
    case DRV_RSA_SIGN_MD5:
950
 
    case DRV_RSA_SIGN_SHA:        
951
 
      /* buf = <<data_len:32/integer, data:data_len/binary,
952
 
       *         rsa_e_len:32/integer, rsa_e:rsa_e_len/binary,       
953
 
       *         rsa_n_len:32/integer, rsa_n:rsa_n_len/binary,
954
 
       *         rsa_d_len:32/integer, rsa_d:rsa_d_len/binary>> */ 
955
 
 
956
 
      ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len);
957
 
 
958
 
      i = 0;
959
 
      j = 0;
960
 
      
961
 
      if (len < 16)
962
 
         return -1;
963
 
      data_len = get_int32(buf + i + j);
964
 
      j += data_len; i += 4;
965
 
      if (len < (16 + j))
966
 
         return -1;
967
 
      rsa_e_len = get_int32(buf + i + j);
968
 
      j += rsa_e_len; i += 4;
969
 
      if (len < (16 + j))
970
 
         return -1;
971
 
      rsa_n_len = get_int32(buf + i + j);
972
 
      j += rsa_n_len; i += 4;
973
 
      if (len < (16 + j))
974
 
         return -1;
975
 
      rsa_d_len = get_int32(buf + i + j);
976
 
      j += rsa_d_len; i += 4;
977
 
      if (len != (16 + j))
978
 
         return -1;
979
 
 
980
 
      i = 4;
981
 
      i += (data_len + 4);
982
 
      rsa_e = BN_new();
983
 
      BN_bin2bn((unsigned char *)(buf + i), rsa_e_len, rsa_e);
984
 
      i += (rsa_e_len + 4);
985
 
      rsa_n = BN_new();
986
 
      BN_bin2bn((unsigned char *)(buf + i), rsa_n_len, rsa_n);
987
 
      i += (rsa_n_len + 4);
988
 
      rsa_d = BN_new();
989
 
      BN_bin2bn((unsigned char *)(buf + i), rsa_d_len, rsa_d);
990
 
      i += (rsa_d_len + 4);
991
 
  
992
 
      rsa = RSA_new();
993
 
      rsa->e = rsa_e;
994
 
      rsa->n = rsa_n;
995
 
      rsa->d = rsa_d;
996
 
      
997
 
      dlen = RSA_size(rsa);
998
 
      bin = return_binary(rbuf,rlen,dlen+1);
999
 
      if (bin==NULL) return -1;
1000
 
      i = 4;
1001
 
      if (command == DRV_RSA_SIGN_MD5) {
1002
 
         MD5((unsigned char *) (buf + i), data_len, (unsigned char *) hmacbuf);
1003
 
         ERL_VALGRIND_ASSERT_MEM_DEFINED(hmacbuf, MD5_DIGEST_LENGTH);
1004
 
         i = RSA_sign(NID_md5,
1005
 
                      (unsigned char *) hmacbuf,MD5_DIGEST_LENGTH,
1006
 
                      (unsigned char *) &bin[1],
1007
 
                      &rsa_s_len, rsa);  
1008
 
      } else {
1009
 
         SHA1((unsigned char *) (buf + i), data_len, 
1010
 
              (unsigned char *) hmacbuf);
1011
 
         ERL_VALGRIND_ASSERT_MEM_DEFINED(hmacbuf, SHA_DIGEST_LENGTH);
1012
 
         i =  RSA_sign(NID_sha1,
1013
 
                       (unsigned char *) hmacbuf,SHA_DIGEST_LENGTH,
1014
 
                       (unsigned char *) &bin[1],
1015
 
                       &rsa_s_len, rsa);
1016
 
      }
1017
 
      RSA_free(rsa);
1018
 
      if (i) {
1019
 
          ERL_VALGRIND_MAKE_MEM_DEFINED(bin+1, rsa_s_len);
1020
 
          if (rsa_s_len != dlen) {
1021
 
              bin = return_binary_shrink(rbuf,rlen,bin,rsa_s_len+1);
1022
 
              ERL_VALGRIND_ASSERT_MEM_DEFINED(bin+1, rsa_s_len);
1023
 
          }
1024
 
          bin[0] = 1;
1025
 
          return rsa_s_len + 1;
1026
 
      }
1027
 
      else {
1028
 
          bin[0] = 0;
1029
 
          return 1;
1030
 
      }
1031
 
 
1032
 
    case DRV_RSA_PRIVATE_DECRYPT:        
1033
 
    case DRV_RSA_PRIVATE_ENCRYPT:        
1034
 
       /* buf = <<data_len:32/integer, data:data_len/binary,
1035
 
        *         rsa_e_len:32/integer, rsa_e:rsa_e_len/binary,       
1036
 
        *         rsa_n_len:32/integer, rsa_n:rsa_n_len/binary,
1037
 
        *         rsa_d_len:32/integer, rsa_d:rsa_d_len/binary,
1038
 
        *         pad:8/integer >> */ 
1039
 
 
1040
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len);
1041
 
       i = 0;
1042
 
       j = 0;
1043
 
      
1044
 
       if (len < 17)
1045
 
          return -1;
1046
 
       data_len = get_int32(buf + i + j);
1047
 
       j += data_len; i += 4;
1048
 
       if (len < (17 + j))
1049
 
          return -1;
1050
 
       rsa_e_len = get_int32(buf + i + j);
1051
 
       j += rsa_e_len; i += 4;
1052
 
       if (len < (17 + j))
1053
 
          return -1;
1054
 
       rsa_n_len = get_int32(buf + i + j);
1055
 
       j += rsa_n_len; i += 4;
1056
 
       if (len < (17 + j))
1057
 
          return -1;
1058
 
       rsa_d_len = get_int32(buf + i + j);
1059
 
       j += rsa_d_len; i += 4;
1060
 
       padding = *(unsigned char *) (buf+i+j); 
1061
 
       if (len != (17 + j))
1062
 
          return -1;
1063
 
 
1064
 
       i = 4;
1065
 
       i += (data_len + 4);
1066
 
       rsa_e = BN_new();
1067
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_e_len);
1068
 
       BN_bin2bn((unsigned char *)(buf + i), rsa_e_len, rsa_e);
1069
 
       i += (rsa_e_len + 4);
1070
 
       rsa_n = BN_new();
1071
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_n_len);
1072
 
       BN_bin2bn((unsigned char *)(buf + i), rsa_n_len, rsa_n);
1073
 
       i += (rsa_n_len + 4);
1074
 
       rsa_d = BN_new();
1075
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_d_len);
1076
 
       BN_bin2bn((unsigned char *)(buf + i), rsa_d_len, rsa_d);
1077
 
       i += (rsa_d_len + 4);
1078
 
       
1079
 
       switch(padding) {
1080
 
       case 0:
1081
 
          padding = RSA_NO_PADDING;
1082
 
          break;
1083
 
       case 1:
1084
 
          padding = RSA_PKCS1_PADDING;
1085
 
          break;
1086
 
       case 2:
1087
 
          padding = RSA_PKCS1_OAEP_PADDING;
1088
 
          break;
1089
 
       case 3:
1090
 
          padding = RSA_SSLV23_PADDING;
1091
 
          break;
1092
 
       default:
1093
 
          return -1;
1094
 
       }
1095
 
       
1096
 
       rsa = RSA_new();
1097
 
       rsa->e = rsa_e;
1098
 
       rsa->n = rsa_n;
1099
 
       rsa->d = rsa_d;
1100
 
      
1101
 
       dlen = RSA_size(rsa) + 1;
1102
 
       bin = return_binary(rbuf,rlen,dlen);
1103
 
       if (bin==NULL) return -1;
1104
 
       i = 4;
1105
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len);
1106
 
       if(command == DRV_RSA_PRIVATE_DECRYPT) {
1107
 
           i = RSA_private_decrypt(data_len, (unsigned char *) (buf+i),
1108
 
                                   (unsigned char *) &bin[1],
1109
 
                                   rsa, padding);          
1110
 
           if(i > 0) {
1111
 
               ERL_VALGRIND_MAKE_MEM_DEFINED(&bin[1],i);
1112
 
               bin = return_binary_shrink(rbuf,rlen, bin, i+1);
1113
 
               if (bin==NULL) return -1;
1114
 
           }
1115
 
       } else {
1116
 
           i = RSA_private_encrypt(data_len, (unsigned char *) (buf+i),
1117
 
                                   (unsigned char *) &bin[1],
1118
 
                                   rsa, padding);
1119
 
           if(i > 0) {
1120
 
               ERL_VALGRIND_MAKE_MEM_DEFINED(&bin[1],i);
1121
 
           }
1122
 
       }
1123
 
       RSA_free(rsa);
1124
 
       if(i > 0) {
1125
 
           bin[0] = 1;
1126
 
           return i + 1;
1127
 
       } else {
1128
 
           bin[0] = 0;
1129
 
           return 1;
1130
 
       }
1131
 
       break;
1132
 
 
1133
 
    case DRV_RSA_PUBLIC_ENCRYPT:
1134
 
    case DRV_RSA_PUBLIC_DECRYPT:
1135
 
       /* buf = <<data_len:32/integer, data:data_len/binary,
1136
 
        *         rsa_e_len:32/integer, rsa_e:rsa_e_len/binary,       
1137
 
        *         rsa_n_len:32/integer, rsa_n:rsa_n_len/binary,
1138
 
        *         pad:8/integer >> */ 
1139
 
 
1140
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len);
1141
 
       i = 0;
1142
 
       j = 0;
1143
 
      
1144
 
       if (len < 13)
1145
 
          return -1;
1146
 
       data_len = get_int32(buf + i + j);
1147
 
       j += data_len; i += 4;
1148
 
       if (len < (13 + j))
1149
 
          return -1;
1150
 
       rsa_e_len = get_int32(buf + i + j);
1151
 
       j += rsa_e_len; i += 4;
1152
 
       if (len < (13 + j))
1153
 
          return -1;
1154
 
       rsa_n_len = get_int32(buf + i + j);
1155
 
       j += rsa_n_len; i += 4;
1156
 
       if (len < (13 + j))
1157
 
          return -1;
1158
 
       padding = *(unsigned char *) (buf + i + j);
1159
 
       if (len != (13 + j))
1160
 
          return -1;
1161
 
 
1162
 
       i = 4;
1163
 
       i += (data_len + 4);
1164
 
       rsa_e = BN_new();
1165
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_e_len);
1166
 
       BN_bin2bn((unsigned char *)(buf + i), rsa_e_len, rsa_e);
1167
 
       i += (rsa_e_len + 4);
1168
 
       rsa_n = BN_new();
1169
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,rsa_n_len);
1170
 
       BN_bin2bn((unsigned char *)(buf + i), rsa_n_len, rsa_n);
1171
 
       i += (rsa_n_len + 4);
1172
 
       
1173
 
       switch(padding) {
1174
 
       case 0:
1175
 
          padding = RSA_NO_PADDING;
1176
 
          break;
1177
 
       case 1:
1178
 
          padding = RSA_PKCS1_PADDING;
1179
 
          break;
1180
 
       case 2:
1181
 
          padding = RSA_PKCS1_OAEP_PADDING;
1182
 
          break;
1183
 
       case 3:
1184
 
          padding = RSA_SSLV23_PADDING;
1185
 
          break;
1186
 
       default:
1187
 
          return -1;
1188
 
       }
1189
 
       
1190
 
       rsa = RSA_new();
1191
 
       rsa->e = rsa_e;
1192
 
       rsa->n = rsa_n;
1193
 
      
1194
 
       dlen = RSA_size(rsa) + 1;
1195
 
       bin = return_binary(rbuf,rlen,dlen);
1196
 
       if (bin==NULL) return -1;
1197
 
       i = 4;
1198
 
       if(command == DRV_RSA_PUBLIC_ENCRYPT) {
1199
 
           ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len);
1200
 
           i = RSA_public_encrypt(data_len, (unsigned char *) (buf+i),
1201
 
                                  (unsigned char *) &bin[1],
1202
 
                                  rsa, padding);
1203
 
           if (i > 0) {
1204
 
               ERL_VALGRIND_MAKE_MEM_DEFINED(bin+1, i);
1205
 
           }
1206
 
       } else {
1207
 
           i = RSA_public_decrypt(data_len, (unsigned char *) (buf+i),
1208
 
                                  (unsigned char *) &bin[1],
1209
 
                                  rsa, padding);           
1210
 
           if(i > 0) {
1211
 
               ERL_VALGRIND_MAKE_MEM_DEFINED(bin+1, i);
1212
 
               bin = return_binary_shrink(rbuf,rlen,bin, i+1);
1213
 
               if (bin==NULL) return -1;
1214
 
           }
1215
 
       }
1216
 
       
1217
 
       RSA_free(rsa);
1218
 
       if(i > 0) {
1219
 
           bin[0] = 1;
1220
 
           return i + 1;
1221
 
       } else {
1222
 
/*        ERR_load_crypto_strings(); */
1223
 
/*        fprintf(stderr, "%d: %s \r\n", __LINE__, ERR_reason_error_string(ERR_get_error())); */
1224
 
           bin[0] = 0;
1225
 
           return 1;
1226
 
       }
1227
 
       break;
1228
 
 
1229
 
    case DRV_CBC_AES128_ENCRYPT:
1230
 
    case DRV_CBC_AES256_ENCRYPT:
1231
 
    case DRV_CBC_AES128_DECRYPT:
1232
 
    case DRV_CBC_AES256_DECRYPT:
1233
 
        /* buf = key[klen] ivec[klen] data */
1234
 
        if (command == DRV_CBC_AES256_ENCRYPT || command == DRV_CBC_AES256_DECRYPT)
1235
 
            klen = 32;
1236
 
        else 
1237
 
            klen = 16;
1238
 
        dlen = len - klen - 16;
1239
 
        if (dlen < 0)
1240
 
            return -1;
1241
 
        if (dlen % 16 != 0)
1242
 
            return -1;
1243
 
        if (command == DRV_CBC_AES128_ENCRYPT || command == DRV_CBC_AES256_ENCRYPT) {
1244
 
            i = AES_ENCRYPT;
1245
 
            AES_set_encrypt_key((unsigned char *) buf, klen*8, &aes_key);
1246
 
        } else {
1247
 
            i = AES_DECRYPT;
1248
 
            AES_set_decrypt_key((unsigned char *) buf, klen*8, &aes_key);
1249
 
        }
1250
 
        bin = return_binary(rbuf,rlen,dlen);
1251
 
        if (bin==NULL) return -1;
1252
 
        AES_cbc_encrypt((unsigned char *) (buf + klen+16),
1253
 
                        (unsigned char *) bin,
1254
 
                        dlen,
1255
 
                        &aes_key, 
1256
 
                        (unsigned char *) (buf + klen),
1257
 
                        i);
1258
 
        return dlen;
1259
 
        
1260
 
/*     case DRV_CBC_AES128_DECRYPT: */
1261
 
/*     case DRV_CBC_AES256_DECRYPT: */
1262
 
/*      /\* buf = key[klen] ivec[16] data *\/ */
1263
 
/*      if (command == DRV_CBC_AES256_DECRYPT) */
1264
 
/*          klen = 32; */
1265
 
/*      else  */
1266
 
/*          klen = 16; */
1267
 
/*      dlen = len - klen - 16; */
1268
 
/*      if (dlen < 0) */
1269
 
/*          return -1; */
1270
 
/*      *rbuf = (char *)(bin = driver_alloc_binary(dlen)); */
1271
 
/*      AES_set_decrypt_key((unsigned char *) buf, klen*8, &aes_key); */
1272
 
/*      AES_cbc_encrypt((unsigned char *) (buf + klen+16), */
1273
 
/*                      (unsigned char *) bin->orig_bytes, */
1274
 
/*                      dlen, */
1275
 
/*                      &aes_key,  */
1276
 
/*                      (unsigned char *) (buf + klen), */
1277
 
/*                      AES_DECRYPT); */
1278
 
/*      return dlen; */
1279
 
/*      break; */
1280
 
 
1281
 
    case DRV_XOR:
1282
 
        /* buf = data1, data2 with same size */
1283
 
        dlen = len / 2;
1284
 
        if (len != dlen * 2)
1285
 
            return -1;
1286
 
        bin = return_binary(rbuf,rlen,dlen);
1287
 
        if (bin==NULL) return -1;
1288
 
        p = bin,
1289
 
        dbuf = buf + dlen;
1290
 
        for (key = buf, key2 = dbuf; key != dbuf; ++key, ++key2, ++p)
1291
 
            *p = *key ^ *key2;
1292
 
        return dlen;
1293
 
        
1294
 
    case DRV_DH_GENERATE_PARAMS:
1295
 
       /* buf = <<PrimeLen:32 Generator:32>> */
1296
 
       if (len != 8) 
1297
 
          return -1;
1298
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len);
1299
 
       prime_len = get_int32(buf);
1300
 
       generator = get_int32(buf+4);
1301
 
       dh_params = DH_generate_parameters(prime_len, generator, NULL, NULL);
1302
 
 
1303
 
       if(dh_params) {
1304
 
          dh_p_len = BN_num_bytes(dh_params->p);
1305
 
          dh_g_len = BN_num_bytes(dh_params->g);
1306
 
          dlen = 1 + 4 + 4 + dh_g_len + dh_p_len;
1307
 
          bin = return_binary(rbuf,rlen,dlen);
1308
 
          if (bin==NULL) return -1;
1309
 
          bin[0] = 1;
1310
 
          put_int32(bin+1, dh_p_len);
1311
 
          BN_bn2bin(dh_params->p, bin+5);
1312
 
          ERL_VALGRIND_MAKE_MEM_DEFINED(bin+5,dh_p_len);
1313
 
          put_int32(bin+5+dh_p_len, dh_g_len);
1314
 
          BN_bn2bin(dh_params->g, bin+5+dh_p_len+4);
1315
 
          ERL_VALGRIND_MAKE_MEM_DEFINED(bin+5+dh_p_len+4,dh_g_len);       
1316
 
       } else {
1317
 
           dlen = 1;
1318
 
           bin = return_binary(rbuf,rlen,dlen);
1319
 
           if (bin==NULL) return -1;
1320
 
           bin[0] = 0;
1321
 
       }
1322
 
       DH_free(dh_params);
1323
 
       return dlen;
1324
 
 
1325
 
    case DRV_DH_CHECK:
1326
 
       /* buf = <<dh_p_len:32/integer, dh_p:dh_p_len/binary,
1327
 
        *         dh_g_len:32/integer, dh_g:dh_g_len/binary>> */
1328
 
       i = 0;
1329
 
       j = 0;
1330
 
       if(len < 8)        return -1;
1331
 
       dh_p_len = get_int32(buf + i + j);
1332
 
       j += dh_p_len; i += 4;
1333
 
       if (len < (8 + j)) return -1;
1334
 
       dh_g_len = get_int32(buf + i + j);
1335
 
       j += dh_g_len; i += 4;
1336
 
       if(len != (8+j))   return -1;
1337
 
       i=4;
1338
 
       dh_p = BN_new();
1339
 
       BN_bin2bn((unsigned char *)(buf + i), dh_p_len, dh_p);
1340
 
       i += (dh_p_len + 4);
1341
 
       dh_g = BN_new();
1342
 
       BN_bin2bn((unsigned char *)(buf + i), dh_g_len, dh_g);
1343
 
       /* i += (dsa_g_len + 4); */
1344
 
 
1345
 
       dh_params = DH_new();
1346
 
       dh_params->p = dh_p;
1347
 
       dh_params->g = dh_g;
1348
 
       
1349
 
       i=0;
1350
 
       bin = return_binary(rbuf,rlen,4);
1351
 
       if (bin==NULL) return -1;
1352
 
       if(DH_check(dh_params, &i)) {
1353
 
          put_int32(bin, i);
1354
 
       } else {
1355
 
          /* Check Failed */
1356
 
          put_int32(bin, -1);
1357
 
       }
1358
 
       DH_free(dh_params);
1359
 
       return 4;
1360
 
 
1361
 
    case DRV_DH_GENERATE_KEY:
1362
 
       /* buf = <<key_len:32,  key:key_len/binary,            *
1363
 
        *         dh_p_len:32/integer, dh_p:dh_p_len/binary,  *
1364
 
        *         dh_g_len:32/integer, dh_g:dh_g_len/binary>> */
1365
 
       ERL_VALGRIND_ASSERT_MEM_DEFINED(buf,len);
1366
 
       i = 0;
1367
 
       j = 0;
1368
 
       if(len < 12)        return -1;
1369
 
       base_len = get_int32(buf + i + j);
1370
 
       j += base_len; i += 4;
1371
 
       if (len < (12 + j)) return -1;
1372
 
       dh_p_len = get_int32(buf + i + j);
1373
 
       j += dh_p_len; i += 4;
1374
 
       if (len < (12 + j)) return -1;
1375
 
       dh_g_len = get_int32(buf + i + j);
1376
 
       j += dh_g_len; i += 4;
1377
 
       if(len != (12 + j))   return -1;
1378
 
       i=4;
1379
 
       i += (base_len + 4);
1380
 
       dh_p = BN_new();
1381
 
       BN_bin2bn((unsigned char *)(buf + i), dh_p_len, dh_p);
1382
 
       i += (dh_p_len + 4);
1383
 
       dh_g = BN_new();
1384
 
       BN_bin2bn((unsigned char *)(buf + i), dh_g_len, dh_g);
1385
 
       /* i += (dsa_g_len + 4); */
1386
 
 
1387
 
       dh_params = DH_new();
1388
 
       dh_params->p = dh_p;
1389
 
       dh_params->g = dh_g;
1390
 
       if(base_len > 0) {
1391
 
           dh_params->priv_key = BN_new();
1392
 
           BN_bin2bn((unsigned char *)(buf + i), base_len, 
1393
 
                     dh_params->priv_key);
1394
 
       }
1395
 
       i=0;
1396
 
       if(DH_generate_key(dh_params)) {
1397
 
          privkey_len = BN_num_bytes(dh_params->priv_key);
1398
 
          pubkey_len = BN_num_bytes(dh_params->pub_key);
1399
 
          dlen = 1 + 4 + 4 + pubkey_len + privkey_len;
1400
 
          bin = return_binary(rbuf,rlen, dlen);
1401
 
          if (bin==NULL) return -1;
1402
 
          bin[0] = 1;
1403
 
          put_int32(bin+1, pubkey_len);
1404
 
          BN_bn2bin(dh_params->pub_key, bin+5);
1405
 
          ERL_VALGRIND_MAKE_MEM_DEFINED(bin+5, pubkey_len);       
1406
 
          put_int32(bin+5+pubkey_len, privkey_len);
1407
 
          BN_bn2bin(dh_params->priv_key, bin+5+pubkey_len+4);
1408
 
          ERL_VALGRIND_MAKE_MEM_DEFINED(bin+5+pubkey_len+4, privkey_len);         
1409
 
       } else {
1410
 
           dlen = 1;
1411
 
           bin = return_binary(rbuf,rlen,dlen);
1412
 
           if (bin==NULL) return -1;
1413
 
           bin[0] = 0;
1414
 
       }
1415
 
       DH_free(dh_params);
1416
 
       return dlen;
1417
 
 
1418
 
    case DRV_DH_COMPUTE_KEY:
1419
 
       /* buf = <<pubkey_len:32,  pubkey:pubkey_len/binary,   *
1420
 
        *         privkey_len:32, privkey:privkey_len/binary, *
1421
 
        *         dh_p_len:32/integer, dh_p:dh_p_len/binary,  *
1422
 
        *         dh_g_len:32/integer, dh_g:dh_g_len/binary>> */
1423
 
       i = 0;
1424
 
       j = 0;
1425
 
       if(len < 16)        return -1;
1426
 
       pubkey_len = get_int32(buf + i + j);
1427
 
       j += pubkey_len; i += 4;
1428
 
       if (len < (16 + j)) return -1;
1429
 
       privkey_len = get_int32(buf + i + j);
1430
 
       j += privkey_len; i += 4;
1431
 
       if (len < (16 + j)) return -1;
1432
 
       dh_p_len = get_int32(buf + i + j);
1433
 
       j += dh_p_len; i += 4;
1434
 
       if (len < (16 + j)) return -1;
1435
 
       dh_g_len = get_int32(buf + i + j);
1436
 
       j += dh_g_len; i += 4;
1437
 
       if(len != (16 + j))   return -1;
1438
 
       i=4;
1439
 
       pubkey = BN_new();
1440
 
       BN_bin2bn((unsigned char *)(buf + i), pubkey_len, pubkey);
1441
 
       i += (pubkey_len + 4);
1442
 
       privkey = BN_new();
1443
 
       BN_bin2bn((unsigned char *)(buf + i), privkey_len, privkey);
1444
 
       i += (privkey_len + 4);
1445
 
       dh_p = BN_new();
1446
 
       BN_bin2bn((unsigned char *)(buf + i), dh_p_len, dh_p);
1447
 
       i += (dh_p_len + 4);
1448
 
       dh_g = BN_new();
1449
 
       BN_bin2bn((unsigned char *)(buf + i), dh_g_len, dh_g);
1450
 
       /* i += (dsa_g_len + 4); */
1451
 
 
1452
 
       dh_params = DH_new();
1453
 
       dh_params->p = dh_p;
1454
 
       dh_params->g = dh_g;
1455
 
       dh_params->priv_key = privkey;
1456
 
       
1457
 
       klen = DH_size(dh_params);
1458
 
       bin = return_binary(rbuf,rlen,1+klen);
1459
 
       if (bin==NULL) return -1;
1460
 
       i = DH_compute_key(&bin[1], pubkey, dh_params);
1461
 
       DH_free(dh_params);
1462
 
       if (i > 0) {
1463
 
           if (i != klen) {
1464
 
               bin = return_binary_shrink(rbuf,rlen,bin,1+i);
1465
 
           }       
1466
 
           bin[0] = 1;
1467
 
           return i + 1;
1468
 
       }
1469
 
       else {
1470
 
           bin[0] = 0;
1471
 
           return 1;
1472
 
       }
1473
 
 
1474
 
    case DRV_MD4:
1475
 
        bin = return_binary(rbuf,rlen,MD4_LEN);
1476
 
        MD4((unsigned char *)buf, len, (unsigned char *)bin);
1477
 
       return MD4_LEN;
1478
 
       
1479
 
    case DRV_MD4_INIT:
1480
 
        bin = return_binary(rbuf,rlen,MD4_CTX_LEN);
1481
 
        MD4_Init((MD4_CTX *) bin);
1482
 
       return MD4_CTX_LEN;
1483
 
       
1484
 
    case DRV_MD4_UPDATE:
1485
 
       if (len < MD4_CTX_LEN)
1486
 
          return -1;
1487
 
       bin = return_binary(rbuf,rlen,MD4_CTX_LEN);
1488
 
       memcpy(bin, buf, MD4_CTX_LEN);
1489
 
       MD4_Update((MD4_CTX *) bin, buf + MD4_CTX_LEN, len - MD4_CTX_LEN);
1490
 
       return MD4_CTX_LEN;
1491
 
       
1492
 
    case DRV_MD4_FINAL:
1493
 
       if (len != MD4_CTX_LEN)
1494
 
          return -1;
1495
 
       memcpy(&md4_ctx, buf, MD4_CTX_LEN); /* XXX Use buf only? */
1496
 
       bin = return_binary(rbuf,rlen,MD4_LEN);
1497
 
       MD4_Final((unsigned char *)bin, &md4_ctx);
1498
 
       return MD4_LEN;
1499
 
 
1500
 
#if SSL_VERSION_0_9_8
1501
 
    case DRV_SHA256:
1502
 
       bin = return_binary(rbuf,rlen,SHA256_LEN);
1503
 
       SHA256(buf, len, bin);
1504
 
       return SHA256_LEN;
1505
 
       
1506
 
    case DRV_SHA256_INIT:
1507
 
        bin = return_binary(rbuf,rlen,SHA256_CTX_LEN);
1508
 
        SHA256_Init((SHA256_CTX *)bin);
1509
 
       return SHA256_CTX_LEN;           
1510
 
 
1511
 
    case DRV_SHA256_UPDATE:
1512
 
       if (len < SHA256_CTX_LEN)
1513
 
          return -1;
1514
 
       bin = return_binary(rbuf,rlen,SHA256_CTX_LEN);
1515
 
       memcpy(bin, buf, SHA256_CTX_LEN);
1516
 
       SHA256_Update((SHA256_CTX *)bin, buf + SHA256_CTX_LEN, 
1517
 
                     len - SHA256_CTX_LEN);
1518
 
       return SHA256_CTX_LEN;           
1519
 
 
1520
 
    case DRV_SHA256_FINAL:
1521
 
       if (len != SHA256_CTX_LEN)
1522
 
          return -1;
1523
 
       memcpy(&sha256_ctx, buf, SHA256_CTX_LEN); /* XXX Use buf only? */
1524
 
       bin = return_binary(rbuf,rlen,SHA256_LEN);
1525
 
       SHA256_Final(bin, &sha256_ctx);
1526
 
       return SHA256_LEN;
1527
 
 
1528
 
    case DRV_SHA512:
1529
 
        bin = return_binary(rbuf,rlen,SHA512_LEN);
1530
 
        SHA512(buf, len, bin);
1531
 
       return SHA512_LEN;
1532
 
       
1533
 
    case DRV_SHA512_INIT:
1534
 
        bin = return_binary(rbuf,rlen,SHA512_CTX_LEN);
1535
 
        SHA512_Init((SHA512_CTX *)bin);
1536
 
       return SHA512_CTX_LEN;           
1537
 
       
1538
 
    case DRV_SHA512_UPDATE:
1539
 
       if (len < SHA512_CTX_LEN)
1540
 
          return -1;
1541
 
        bin = return_binary(rbuf,rlen,SHA512_CTX_LEN);
1542
 
        memcpy(bin, buf, SHA512_CTX_LEN);
1543
 
        SHA512_Update((SHA512_CTX *)bin, buf + SHA512_CTX_LEN, 
1544
 
                     len - SHA512_CTX_LEN);
1545
 
       return SHA512_CTX_LEN;           
1546
 
       
1547
 
    case DRV_SHA512_FINAL:
1548
 
       if (len != SHA512_CTX_LEN)
1549
 
          return -1;
1550
 
       memcpy(&sha512_ctx, buf, SHA512_CTX_LEN); /* XXX Use buf only? */
1551
 
       bin = return_binary(rbuf,rlen,SHA512_LEN));
1552
 
       SHA512_Final(bin, &sha512_ctx);
1553
 
       return SHA512_LEN;               
1554
 
#endif
1555
 
       
1556
 
    case DRV_INFO_LIB:  
1557
 
       {/* <<DrvVer:8, NameSize:8, Name:NameSize/binary, VerNum:32, VerStr/binary>> */
1558
 
          static const char libname[] = "OpenSSL";
1559
 
          unsigned name_sz = strlen(libname);
1560
 
          const char* ver = SSLeay_version(SSLEAY_VERSION);
1561
 
          unsigned ver_sz = strlen(ver);
1562
 
          dlen = 1+1+name_sz+4+ver_sz;
1563
 
          bin = return_binary(rbuf, rlen, dlen);
1564
 
          if (bin==NULL) return -1;
1565
 
          p = bin;
1566
 
          *p++ = 0; /* "driver version" for future use */
1567
 
          *p++ = name_sz;
1568
 
          memcpy(p, libname, name_sz);
1569
 
          p += name_sz;
1570
 
          put_int32(p,SSLeay()); /* OPENSSL_VERSION_NUMBER */
1571
 
          p += 4;
1572
 
          memcpy(p, ver, ver_sz);
1573
 
       }
1574
 
       return dlen;
1575
 
 
1576
 
    default:
1577
 
       break;
1578
 
    }
1579
 
    return -1;
1580
 
}
1581
 
 
1582
 
 
1583
 
#ifdef OPENSSL_THREADS /* vvvvvvvvvvvvvvv OPENSSL_THREADS vvvvvvvvvvvvvvvv */
1584
 
 
1585
 
static INLINE void locking(int mode, ErlDrvRWLock* lock)
1586
 
{
1587
 
    switch(mode) {
1588
 
    case CRYPTO_LOCK|CRYPTO_READ:
1589
 
        erl_drv_rwlock_rlock(lock);
1590
 
        break;
1591
 
    case CRYPTO_LOCK|CRYPTO_WRITE:
1592
 
        erl_drv_rwlock_rwlock(lock);
1593
 
        break;
1594
 
    case CRYPTO_UNLOCK|CRYPTO_READ:
1595
 
        erl_drv_rwlock_runlock(lock);
1596
 
        break;
1597
 
    case CRYPTO_UNLOCK|CRYPTO_WRITE:
1598
 
        erl_drv_rwlock_rwunlock(lock);
1599
 
        break;
1600
 
    default:
1601
 
        ASSERT(!"Invalid lock mode");
1602
 
    }
1603
 
}
1604
 
 
1605
 
/* Callback from openssl for static locking
1606
 
 */
1607
 
static void locking_function(int mode, int n, const char *file, int line)
1608
 
{
1609
 
    ASSERT(n>=0 && n<CRYPTO_num_locks());
1610
 
 
1611
 
    locking(mode, lock_vec[n]);
1612
 
}
1613
 
 
1614
 
/* Callback from openssl for thread id
1615
 
 */
1616
 
static unsigned long id_function(void)
1617
 
{
1618
 
    return (unsigned long) erl_drv_thread_self();
1619
 
}
1620
 
 
1621
 
/* Callbacks for dynamic locking, not used by current openssl version (0.9.8)
1622
 
 */
1623
 
static struct CRYPTO_dynlock_value* dyn_create_function(const char *file, int line)
1624
 
{
1625
 
    return (struct CRYPTO_dynlock_value*) erl_drv_rwlock_create("crypto_drv_dyn");
1626
 
}
1627
 
static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value* ptr,const char *file, int line)
1628
 
{
1629
 
    locking(mode, (ErlDrvRWLock*)ptr);
1630
 
}
1631
 
static void dyn_destroy_function(struct CRYPTO_dynlock_value *ptr, const char *file, int line)
1632
 
{
1633
 
    erl_drv_rwlock_destroy((ErlDrvRWLock*)ptr);
1634
 
}
1635
 
 
1636
 
#endif /* ^^^^^^^^^^^^^^^^^^^^^^ OPENSSL_THREADS ^^^^^^^^^^^^^^^^^^^^^^ */
1637
 
    
1638
 
/* HMAC */
1639
 
 
1640
 
static void hmac_md5(char *key, int klen, char *dbuf, int dlen, char *hmacbuf)
1641
 
{
1642
 
    MD5_CTX ctx;
1643
 
    char ipad[HMAC_INT_LEN];
1644
 
    char opad[HMAC_INT_LEN];
1645
 
    unsigned char nkey[MD5_LEN];
1646
 
    int i;
1647
 
 
1648
 
    /* Change key if longer than 64 bytes */
1649
 
    if (klen > HMAC_INT_LEN) {
1650
 
        MD5_CTX kctx;
1651
 
 
1652
 
        MD5_Init(&kctx);
1653
 
        MD5_Update(&kctx, key, klen);
1654
 
        MD5_Final(nkey, &kctx);
1655
 
        key = (char *) nkey;
1656
 
        klen = MD5_LEN;
1657
 
    }
1658
 
 
1659
 
    memset(ipad, '\0', sizeof(ipad));
1660
 
    memset(opad, '\0', sizeof(opad));
1661
 
    memcpy(ipad, key, klen);
1662
 
    memcpy(opad, key, klen);
1663
 
 
1664
 
    for (i = 0; i < HMAC_INT_LEN; i++) {
1665
 
        ipad[i] ^= HMAC_IPAD;
1666
 
        opad[i] ^= HMAC_OPAD;
1667
 
    }
1668
 
 
1669
 
    /* inner MD5 */
1670
 
    MD5_Init(&ctx);
1671
 
    MD5_Update(&ctx, ipad, HMAC_INT_LEN);
1672
 
    MD5_Update(&ctx, dbuf, dlen);
1673
 
    MD5_Final((unsigned char *) hmacbuf, &ctx);
1674
 
    /* outer MD5 */
1675
 
    MD5_Init(&ctx);
1676
 
    MD5_Update(&ctx, opad, HMAC_INT_LEN);
1677
 
    MD5_Update(&ctx, hmacbuf, MD5_LEN);
1678
 
    MD5_Final((unsigned char *) hmacbuf, &ctx);
1679
 
}
1680
 
 
1681
 
static void hmac_sha1(char *key, int klen, char *dbuf, int dlen, 
1682
 
                      char *hmacbuf)
1683
 
{
1684
 
    SHA_CTX ctx;
1685
 
    char ipad[HMAC_INT_LEN];
1686
 
    char opad[HMAC_INT_LEN];
1687
 
    unsigned char nkey[SHA_LEN];
1688
 
    int i;
1689
 
 
1690
 
    /* Change key if longer than 64 bytes */
1691
 
    if (klen > HMAC_INT_LEN) {
1692
 
        SHA_CTX kctx;
1693
 
 
1694
 
        SHA1_Init(&kctx);
1695
 
        SHA1_Update(&kctx, key, klen);
1696
 
        SHA1_Final(nkey, &kctx);
1697
 
        key = (char *) nkey;
1698
 
        klen = SHA_LEN;
1699
 
    }
1700
 
 
1701
 
    memset(ipad, '\0', sizeof(ipad));
1702
 
    memset(opad, '\0', sizeof(opad));
1703
 
    memcpy(ipad, key, klen);
1704
 
    memcpy(opad, key, klen);
1705
 
 
1706
 
    for (i = 0; i < HMAC_INT_LEN; i++) {
1707
 
        ipad[i] ^= HMAC_IPAD;
1708
 
        opad[i] ^= HMAC_OPAD;
1709
 
    }
1710
 
 
1711
 
    /* inner SHA */
1712
 
    SHA1_Init(&ctx);
1713
 
    SHA1_Update(&ctx, ipad, HMAC_INT_LEN);
1714
 
    SHA1_Update(&ctx, dbuf, dlen);
1715
 
    SHA1_Final((unsigned char *) hmacbuf, &ctx);
1716
 
    /* outer SHA */
1717
 
    SHA1_Init(&ctx);
1718
 
    SHA1_Update(&ctx, opad, HMAC_INT_LEN);
1719
 
    SHA1_Update(&ctx, hmacbuf, SHA_LEN);
1720
 
    SHA1_Final((unsigned char *) hmacbuf, &ctx);
1721
 
}