summaryrefslogtreecommitdiff
path: root/src/DES.c
blob: 2987956b121741e68d48d1e9a3a530b2b291c0cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 *  DES.c: DES/3DES support for PyCrypto using LibTomCrypt
 *
 * Written in 2009 by Dwayne C. Litzenberger <dlitz@dlitz.net>
 *
 * ===================================================================
 * The contents of this file are dedicated to the public domain.  To
 * the extent that dedication to the public domain is not available,
 * everyone is granted a worldwide, perpetual, royalty-free,
 * non-exclusive license to exercise all rights associated with the
 * contents of this file for any purpose whatsoever.
 * No rights are reserved.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * ===================================================================
 *
 * Country of origin: Canada
 */

#include "pycrypto_common.h"

/* Setting this will cause LibTomCrypt to return CRYPT_INVALID_ARG when its
 * assert-like LTC_ARGCHK macro fails. */
#define ARGTYPE 4

/* Include the actial DES implementation */
#include "libtom/tomcrypt_des.c"

#include <assert.h>

typedef struct {
    symmetric_key sk;
} block_state;

static void ltcseterr(int rc)
{
    /* error */
    switch (rc) {
    case CRYPT_INVALID_ARG:
        PyErr_SetString(PyExc_AssertionError, "CRYPT_INVALID_ARG");
        break;

    case CRYPT_INVALID_KEYSIZE:
#ifdef PCT_DES3_MODULE
        PyErr_SetString(PyExc_ValueError, "Invalid key size (must be either 16 or 24 bytes long)");
#else
        PyErr_SetString(PyExc_ValueError, "Invalid key size (must be 8 bytes long)");
#endif
        break;

    case CRYPT_INVALID_ROUNDS:
        PyErr_SetString(PyExc_ValueError, "Invalid number of rounds specified");
        break;

    default:
        PyErr_Format(PyExc_RuntimeError,
            "unexpected run-time error (LTC#%d)", rc);
    }
}

static void block_init(block_state *self, unsigned char *key, int keylen)
{
    int rc;
#ifdef PCT_DES3_MODULE
    int i;
    unsigned char keybuf[24];
    if (keylen == 16) {
        /* "Two-key 3DES" mode, where the 3DES key is K1,K2,K1 */
        for (i = 0; i < 16; i++) {
            keybuf[i] = key[i];
        }
        for (i = 0; i < 8; i++) {
            keybuf[i+16] = key[i];
        }
        rc = des3_setup(keybuf, 24, 0, &self->sk);
        for (i = 0; i < 24; i++) {  /* TODO: securely zeroize this */
            keybuf[i] = 0;
        }
    } else {
        rc = des3_setup(key, keylen, 0, &self->sk);
    }
#else
    rc = des_setup(key, keylen, 0, &self->sk);
#endif
    if (rc != CRYPT_OK) {
        ltcseterr(rc);
    }
}

static void block_finalize(block_state *self)
{
}

static void block_encrypt(block_state *self, unsigned char *in, unsigned char *out)
{
    int rc;
#ifdef PCT_DES3_MODULE
    rc = des3_ecb_encrypt(in, out, &self->sk);
#else
    rc = des_ecb_encrypt(in, out, &self->sk);
#endif
    assert(rc == CRYPT_OK);
}

static void block_decrypt(block_state *self, unsigned char *in, unsigned char *out)
{
    int rc;
#ifdef PCT_DES3_MODULE
    rc = des3_ecb_decrypt(in, out, &self->sk);
#else
    rc = des_ecb_decrypt(in, out, &self->sk);
#endif
    assert(rc == CRYPT_OK);
}

#ifdef PCT_DES3_MODULE
# define MODULE_NAME _DES3   /* triple DES */
# define BLOCK_SIZE 8       /* 64-bit block size */
# define KEY_SIZE  0        /* variable key size (can be 128 or 192 bits (including parity) */
#else
# define MODULE_NAME _DES   /* single DES */
# define BLOCK_SIZE 8       /* 64-bit block size */
# define KEY_SIZE  8        /* 64-bit keys (including parity) */
#endif
#include "block_template.c"