summaryrefslogtreecommitdiff
path: root/src/DES.c
blob: 65171fb9a3a0c19c228a7418f022193f880fd074 (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
/*
 *  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"

#undef DES  /* this is needed because tomcrypt_custom.h defines DES to an empty string */

#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
    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"