76
84
class McryptWarning(UserWarning):
79
cdef class mcrypt(object):
80
'''mcrypt([algo[, mode]]) -> mcrypt
82
Creates a new mcrypt object using the specified algorithm and
83
mode; the default algorithm is Rijndael-128 (also known as the
84
Advanced Encryption Standard (AES) in the United States) and the
85
default mode is CBC (cipher-block chaining). These should be
86
suitable defaults for many applications, but of course you can
87
specify any of the ALGO_* or MODE_* constants should the defaults
90
Also, do not rely on the defaults being the same forever. If a
91
problem is found with the default algorithm or mode, it may be
92
changed. Always specify the algorithm and mode explicitly if you
93
depend on it being a particular way, particularly when decrypting.
95
Furthermore, the caller can pass keyword arguments to the
98
salt: The salt to use with the key derivation algorithm. It
99
must be at least 8 bytes; salt values smaller than this will be
100
rejected. A string or Unicode object can be passed in as the
101
salt, in which case it will be converted to a UTF-8 bytestring
104
password: The password to use with the key derivation algorithm.
105
It should be at least 10 bytes, and it can be an arbitrary
106
collection of bytes. If the password provided is a Python
107
string or Unicode object, it will be converted to a UTF-8
108
bytestring before use. If the password is less than 10 bytes,
109
it will be rejected unless the keyword argument
110
"allow_unsafe_password" is passed and its value is True.
112
iterations: The number of iterations that the key derivation
113
function will use. If unspecified, the KDF will be run through
114
10,000 iterations. Values lower than 1,000 will be rejected
115
unless the keyword argument "allow_unsafe_iterations" is passed
116
and its value is True.
118
iv: The IV (initialization vector), for algorithms that support
119
and/or require one. The provided IV must be precisely the
120
correct size for the specified algorithm and mode, or a
121
ValueError will be raised. If an IV is provided and is not
122
necessary, a ValueError will be raised.
124
All other keyword arguments are silently ignored, since it is
125
possible that new arguments may be made available in the
87
class McryptSecurityWarning(McryptWarning):
91
'''_s2b(value) -> bytes
93
Returns the value as a bytestring if it is possible to do so.
94
If the value is not a string, it will try to get a string from
95
it before attempting conversion. This function will always
96
use UTF-8 encoding.'''
97
if isinstance(value, bytes):
99
elif isinstance(value, unicode):
100
return value.encode('utf8')
101
elif (PY_MAJOR_VERSION < 3) and isinstance(value, str):
102
return value.decode('utf8')
108
raise TypeError('value not a string and not convertable')
111
def pbkdf1(password, salt, iterCount, keyLen, **kwargs):
112
supported = { 'md5': { 'mkl': 16, 'class': hashlib.md5 },
113
'sha1': { 'mkl': 20, 'class': hashlib.sha1 } }
114
if 'algo' not in kwargs:
115
raise ValueError('algo parameter must be md5 or sha1')
116
if kwargs['algo'] == 'md2':
117
raise ValueError('md2 is unsupported')
118
if kwargs['algo'] not in supported:
119
raise ValueError('algo parameter must be md5 or sha1')
121
max_key_len = supported[kwargs['algo']]['mkl']
122
hasher_class = supported[kwargs['algo']]['class']
126
elif keyLen > max_key_len:
127
msg = 'max key size for algo {0} is {1}'
128
raise ValueError(msg.format(kwargs['algo'], max_key_len))
131
h.update(password + salt)
134
for i in range(iterCount - 1):
141
def pbkdf2(password, salt, iterCount, keyLen, **kwargs):
142
cdef unsigned char *out = <unsigned char *>malloc(keyLen)
143
cmc.PKCS5_PBKDF2_HMAC_SHA1(password, len(password),
145
iterCount, keyLen, out)
146
retval = out[:keyLen]
151
cdef class _mcrypt_base(object):
152
'''_mcrypt_base([algo[, mode]]) -> _mcrypt_base
154
This is a very basic class and is not intended to be used by
155
Python code. It contains all of the functionality that can be
156
used by all subclasses, as well as common data fields. This class
157
does not itself actually perform any encryption or decryption.'''
159
# The underlying (native code) cipherstream object, provided by
160
# the mcrypt library. It is a pointer to an opaque C struct.
128
161
cdef cmc.CRYPT_STREAM* _mcStream
130
# Private (inaccessible from Python) attributes
131
163
cdef bint _initialized
132
cdef char* _algorithm
165
# One of "encrypt", "decrypt", "none"
168
# KDF and encryption/decryption parameters
172
cdef int _kdf_iterations
140
cdef bytes _blockSize
143
'''Not used at this time.'''
146
def __init__(self, algo = ALGO_RIJNDAEL128, mode = MODE_CBC, **kwargs):
147
'''Initializes an instance of an mcrypt object.
149
See the class docstring for a description of what this does
150
and what parameters it accepts.'''
151
algo = self._s2b(algo) if type(algo) != bytes else algo
152
mode = self._s2b(mode) if type(mode) != bytes else mode
154
self._mcStream = cmc.mcrypt_module_open(algo, NULL, mode, NULL)
156
if self._mcStream is NULL:
157
raise McryptError('mcrypt init failed: ')
175
# object-lifetime static data
176
cdef char* _algorithm
178
cdef _avail_key_sizes
182
def __init__(self, algo = ALGO_DEFAULT, mode = MODE_DEFAULT):
183
'''Initializes the base object.'''
184
self._open_mcrypt(_s2b(algo), _s2b(mode))
188
self._initialized = True
159
192
self._algorithm = algo
160
193
self._mode = mode
163
self._initParameters(**kwargs)
169
self._initialized = True
172
197
def __dealloc__(self):
178
203
'''close() -> None
180
Closes the module. If the constructor succeeded, then you
181
must call this function when you are finished with the mcrypt
183
if self._mcStream is NULL:
184
raise McryptError('cannot close: not open')
205
Closes the underlying native mcrypt object.'''
206
if self._initialized == False:
207
raise McryptError('not open')
186
cmc.mcrypt_module_close(self._mcStream)
187
self._mcStream = NULL
212
def get_allowed_key_sizes(self):
213
'''get_allowed_key_sizes() -> list of int
214
Retrieves the allowed key sizes.'''
215
return self._avail_key_sizes[:]
217
def get_block_size(self):
218
return self._block_size
222
Retrieve the current IV block, or None if none.'''
223
if (self._iv_len == 0) or (len(self._iv) == 0):
228
def get_iv_len(self):
229
'''get_iv_len() -> int
230
Retrieve the IV length, or 0 if no IV needed.'''
234
'''get_key() -> bytes
235
Retrieves the encryption key.
237
There is often no need to do this, so doing this is not
238
recommended and will issue a McryptSecurityWarning. Most
239
likely one will only use this when attempting to debug any
240
interoperability issues (if any arise) having to do with key
242
warnings.warn('get_key() is not recommended',
243
McryptSecurityWarning)
244
klen = len(self._key)
245
if klen == 0 or klen not in self._avail_key_sizes:
249
def get_parameters(self):
250
'''get_parameters() -> dict
251
Retrieves the parameters for repeat or inverse operations.
253
The one parameter that is not present in the dict is the key.
254
The key is assumed to be known and regenerated, and the
255
regenerated key can be coupled with these parameters to, for
256
example, perform a decryption when the present operation is an
258
def _to_hex(bytestr):
259
return ''.join(['{0:02x}'.format(x) for x in bytestr])
263
retval['algorithm'] = self._algorithm.decode('utf8')
264
retval['mode'] = self._mode.decode('utf8')
268
elif len(self._iv) > 0:
269
retval['iv'] = _to_hex(self._iv)
273
retval['salt'] = _to_hex(self._salt)
190
276
def get_salt(self):
191
if self._salt is None:
277
'''Retrieve the salt value.'''
193
278
if len(self._salt) == 0:
196
281
return self._salt
198
def set_password(self, password, allow_unsafe = False,
199
kdf = None, **kdfparams):
200
'''set_password(password[, allow_unsafe[, kdf[, *kdfparams]]])
202
Sets the key to be used for encryption or decryption. If
203
allow_unsafe is True, this function will allow passwords that
204
are shorter than 10 bytes in length. Presumably, one is using
205
this module because they are interested in providing some sort
206
of security for their data, so this should not be a problem.
208
The caller can specify a custom KDF (key derivation function).
209
A custom-provided KDF has the following function signature:
211
kdf(password, salt, iterCount, keyLen[, kdfparams]) -> key
213
Where the password and salt are bytestrings (<class 'bytes'>
214
in Python 3, or <type 'str'> in Python 2), iterCount is the
215
number of iterations to perform, and keyLen is the length of
216
the key (in BYTES, not BITS). This can be used if, for
217
example, an application requires compatibility with another
218
application that uses a non-standard KDF. The KDF must be
219
able to generate a key of the appropriate size for the
220
algorithm/mode pair in use (if it cannot, a call to this
221
function will raise ValueError).
223
If the salt is not set when this function is called, the salt
224
will be set to a random 8-byte (64-bit) value before calling
225
the KDF. To reproduce the key in the future, the caller must
226
be certain to call .get_salt() and retain that value.
228
By default, this function uses the PBKDF2 function from
229
OpenSSL; also, instance._pbkdf1 is a valid KDF, where
230
"instance" is the name of the instance of an mcrypt object.
231
If any custom keyword arguments need to be passed to the
232
KDF, they can be passed after the kdf parameter.'''
283
# XXX: function-length
284
def set_parameters(self, passwd, salt = None, iv = None,
285
kdf = None, iters = 10000, klen = 0,
287
'''set_parameters(passwd[, salt[, iv[, kdf[, iters[, klen]]]]])
288
Set the password for key generation.
290
If salt is not specified, a new salt that is at least 8-bytes
291
long will be generated. If iv is not specified, a new IV (if
292
one is required) will be generated. If iters is not
293
specified, a default of 10,000 is used. If klen (key length)
294
is not specified, the default is to use the largest key length
295
permitted by the current (algorithm, mode) pairs.
297
If kdf is not specified, the default key derivation function
298
(PBKDF2) will be used. Otherwise, a KDF function must be
299
passed in, and the KDF must look like this:
301
kdf(password, salt, iters, klen, **kwargs) -> key
303
All keyword arguments are passed to the KDF, for extensibility
306
Note that setting these parameters will rerun the KDF. This
307
can take a noticable amount of time on a slow system, or even
308
on a fast system when using a very large number of iterations.
309
Since we do not save the password at all, it must be provided
310
every time the user wants to generate the same key.'''
236
_pass = self._s2b(password)
238
if self._salt is None:
240
if len(self._salt) == 0:
243
if len(_pass) < 10 and allow_unsafe == False:
244
raise ValueError('password must be >= 10 bytes long')
246
if self._key_length == 0:
247
self._key_length = self.get_max_key_length()
249
self._key = kdf(_pass, self._salt, self._iterations,
250
self._key_length, **kdfparams)
253
def get_max_key_length(self):
254
return cmc.mcrypt_enc_get_key_size(self._mcStream)
257
'''Returns the encryption key as a bytestring.
259
This function may disappear at some point, as it is not
260
strictly speaking necessary.'''
261
if self._key is None:
262
raise ValueError('key is not set')
263
if len(self._key) < 8:
264
raise ValueError('key is not set')
268
def set_salt(self, salt = None):
271
Sets the salt value to use with the password when creating the
272
key for encryption or decryption. If no value is provided, a
273
random 8-byte salt value will be created. If a value is
274
provided, it must be at least 8 bytes long. A string or
275
Unicode object can be passed in as the salt, in which case it
276
will be converted to a UTF-8 bytestring before use.'''
279
salt = self._s2b(salt)
282
raise ValueError('Salt is less than min len of 8 bytes')
287
def set_iterations(self, iterCount = 10000):
288
'''set_iterations([iterCount])
290
Sets the number of iterations to use for creating the
291
password. This number is passed to a KDF when creating the
292
key from the password. If not supplied, the value will be
293
reset to the default of 10,000; otherwise, the value must be
294
greater than 0 (and a warning will be raised if the value is
295
less than 1,000, as this would be considered to be woefully
297
self._iterations = iterCount
299
msg = 'insecure # of iterations: {}'.format(iterCount)
300
warnings.warn(msg, McryptWarning)
303
'''Initializes the IV metadata.'''
304
self._ivSize = cmc.mcrypt_enc_get_iv_size(self._mcStream)
307
def _initParameters(self, **kwargs):
309
allow_unsafe_salt = False
311
if ('allow_unsafe_salt' in kwargs) and \
312
(kwargs['allow_unsafe_salt'] == True):
313
allow_unsafe_salt = True
314
self.set_salt(kwargs['salt'], allow_unsafe_salt)
316
self._salt = self.set_salt(None)
318
if 'password' in kwargs:
319
allow_unsafe_password = False
321
if ('allow_unsafe_password' in kwargs) and \
322
(kwargs['allow_unsafe_password'] == True):
323
allow_unsafe_password = True
324
self.set_password(kwargs['password'],
325
allow_unsafe_password)
329
if 'iterations' in kwargs:
330
allow_unsafe_iterations = False
332
if ('allow_unsafe_iterations' in kwargs) and \
333
(kwargs['allow_unsafe_iterations'] == True):
334
allow_unsafe_iterations = True
335
self.set_iterations(kwargs['iterations'],
336
allow_unsafe_iterations)
338
self._iterations = 10000
341
self.set_iv(kwargs['iv'])
345
def _pbkdf2(self, password, salt, iterCount, keyLen, **kwargs):
346
cdef unsigned char *out = <unsigned char *>malloc(keyLen)
347
cmc.PKCS5_PBKDF2_HMAC_SHA1(password, len(password),
349
iterCount, keyLen, out)
350
retval = out[:keyLen]
355
# XXX: function length
356
def _pbkdf1(self, password, salt, iterCount, keyLen, **kwargs):
357
supported = { 'md5': { 'mkl': 16, 'class': hashlib.md5 },
358
'sha1': { 'mkl': 20, 'class': hashlib.sha1 } }
359
if 'algo' not in kwargs:
360
raise ValueError('algo parameter must be md5 or sha1')
361
if kwargs['algo'] == 'md2':
362
raise ValueError('md2 is unsupported')
363
if kwargs['algo'] not in supported:
364
raise ValueError('algo parameter must be md5 or sha1')
366
max_key_len = supported[kwargs['algo']]['mkl']
367
hasher_class = supported[kwargs['algo']]['class']
371
elif keyLen > max_key_len:
372
msg = 'max key size for algo {} is {}'
373
raise ValueError(msg.format(kwargs['algo'], max_key_len))
376
h.update(password + salt)
379
for i in range(iterCount - 1):
386
def _s2b(self, value):
387
'''_s2b(value) -> bytes
389
Returns the value as a bytestring if it is possible to do so.
390
If the value is not a string, it will try to get a string from
391
it before attempting conversion. This function will always
392
use UTF-8 encoding.'''
393
if isinstance(value, bytes):
395
elif isinstance(value, unicode):
396
return value.encode('utf8')
397
elif (PY_MAJOR_VERSION < 3) and isinstance(value, str):
398
return value.decode('utf8')
404
raise TypeError('value not a string and not convertable')
407
cdef class shitty_mcrypt(object):
408
'''The wrapper class for mcrypt.'''
409
cdef cmc.CRYPT_STREAM *_mcrypt_stream
414
cdef bint _initialized
416
cdef bint _ivRequired
423
'''Low-level object initialization.'''
426
def _decode_parameter(self, param):
427
if isinstance(param, bytes):
429
if isinstance(param, unicode):
430
return param.encode('utf8')
431
elif (PY_MAJOR_VERSION < 3) and isinstance(param, str):
432
return param.decode('utf8')
434
raise TypeError('parameter must be a string')
436
def __init__(self, algorithm, mode, **kwargs):
437
'''Initializes an mcrypt instance.
439
Note that this function must always be called: that means that
440
if this class is subclassed for any reason, you MUST make sure
441
that you call up to this constructor!
443
As best as I can tell, the underlying API is not thread-safe;
444
a single object must only be used by a single thread, or the
445
program must exercise extreme care in accessing the object
446
concurrently from multiple threads.
448
After the object has been initialized, it can be used for
449
encrypting any sort of input.
453
algo_dir: The directory containing the module housing the
454
custom algorithm. If you don't know what this is, you need
457
mode_dir: The directory containing the module housing the
458
custom mode. If you don't know what this is, you need not
462
_algo = self._decode_parameter(algorithm)
463
_mode = self._decode_parameter(mode)
465
self._openModule(_algo, _mode, **kwargs)
466
if self._mcrypt_stream is NULL:
467
raise Exception('mcrypt failed')
472
self._blockSize = cmc.mcrypt_enc_get_block_size(self._mcrypt_stream)
473
self._ivRequired = cmc.mcrypt_enc_mode_has_iv(self._mcrypt_stream)
476
self.iv = <char *>malloc(cmc.mcrypt_enc_get_iv_size(self._mcrypt_stream))
478
self._initialized = True
482
def _openModule(self, _algo, _mode, **kwargs):
486
if 'algo_dir' in kwargs:
487
_algo_dir = self._decode_parameter(kwargs['algo_dir'])
489
if 'algo_dir' in kwargs:
490
_mode_dir = self._decode_parameter(kwargs['algo_dir'])
492
if (_algo_dir is None) and (_mode_dir is None):
493
self._mcrypt_stream = cmc.mcrypt_module_open(_algo, NULL,
495
elif (_algo_dir is None) and (_mode_dir is not None):
496
self._mcrypt_stream = cmc.mcrypt_module_open(_algo, NULL,
498
elif (_algo_dir is not None) and (_mode_dir is None):
499
self._mcrypt_stream = cmc.mcrypt_module_open(_algo, _algo_dir,
502
self._mcrypt_stream = cmc.mcrypt_module_open(_algo, _algo_dir,
507
def get_iv_size(self):
508
'''Retrieves the size of the IV required for this instance.
510
If no IV is required, returns None to the caller; otherwise,
511
the size of the IV is returned to the caller.
513
Note that the IV size is in BYTES, not BITS.'''
515
# Note: we do it this way because cmc.mcrypt_enc_mode_has_iv
516
# may provide misleading results if the algorithm requires an
517
# IV even when the current mode does not.
518
iv_size = cmc.mcrypt_enc_get_iv_size(self._mcrypt_stream)
524
def get_key_size(self):
525
'''Retrieves the max supported key size.
527
Note that the algorithm set for the instance may support key
528
sizes other than the maximum; to find that out, use
529
get_key_sizes(), which will return all permitted key sizes.
531
Note that the key size is in BYTES, not BITS.'''
532
return cmc.mcrypt_enc_get_key_size(self._mcrypt_stream)
534
def set_password(self, password, salt = None):
535
'''Sets the (encryption, decryption) password.
537
The actual password is not saved: instead, the password is
538
converted into a key, which is then used for the encryption
541
This function uses the OpenSSL implementation of the PBKDF2
543
salt = self._process_salt(salt)
547
self.key = self._set_key_pbkdf2(password, salt, iterCount,
549
return (self.salt, self.key)
551
def get_block_size(self):
552
'''Retrieves the block size.
554
Note that the block size is in BYTES, not BITS.'''
555
return cmc.mcrypt_enc_get_block_size(self._mcrypt_stream)
557
def generate_random_iv(self):
558
'''Generates a pseudorandom IV value.
560
Please note that this function makes NO CLAIM that the IV is
561
selected with enough entropy to be universally useful. If you
562
have a preferred method of generating IVs which you feel is
563
better than this method (which honestly is quite simplistic)
564
then please feel free to let me know what it is and why it is
565
better. This code does not make any effort to generate
566
high-quality random numbers. Of course, one should rely on
567
the secrecy of the key for security, and not necessarily the
569
iv_size = self.get_iv_size()
573
self.iv = os.urandom(iv_size)
577
'''Retrieves the IV, if set.'''
580
def _get_key(self, password, salt = None, length = 256):
581
'''Fetches a very strong key.'''
582
salt = self._process_salt(salt)
585
return (salt, self._set_key_mtkdf0(password, salt,
588
def _process_salt(self, salt):
592
raise ValueError('Salt must be > 8 bytes long')
593
elif type(salt) != bytes:
594
raise TypeError('Salt must be bytes, got {}'.format(type(salt)))
598
def _set_key_pbkdf1(self, password, salt, iterCount, keyLen = 0,
600
supportedAlgos = { 'md5': { 'max_key_len': 16,
601
'class': hashlib.md5 },
602
'sha1': { 'max_key_len': 20,
603
'class': hashlib.sha1 } }
605
raise ValueError('md2 is unsupported (insecure since 2004)')
606
elif algo not in supportedAlgos:
607
raise ValueError('algo {} unsupported by PBKDF1'.format(algo))
609
mkl = supportedAlgos[algo]['max_key_len']
613
raise ValueError('max key len must not be > {}'.format(mkl))
615
passwd = self._decode_parameter(password)
617
hasherClass = supportedAlgos[algo]['class']
618
hasher = hasherClass()
619
hasher.update(passwd + salt)
620
hashOutput = hasher.digest()
622
for i in range(iterCount - 1):
623
hasher = hasherClass()
624
hasher.update(hashOutput)
625
hashOutput = hasher.digest()
627
return hashOutput[:keyLen]
629
def _set_key_mtkdf0(self, password, salt, iterCount, keyLen = 0,
639
raise ValueError('algo {} unsupported'.format(algo))
641
requiredBlocks = math.ceil(keyLen / blockSize)
643
for blk in range(requiredBlocks):
644
sub_iters = math.ceil(iterCount / requiredBlocks) + iteration
645
thisBlock = self._set_key_pbkdf1(password, salt,
648
keyparts.append(thisBlock)
651
for part in keyparts:
654
return bytes[:keyLen]
656
def _set_key_pbkdf2(self, password, salt, iterCount, keyLen):
658
raise ValueError('No point to such a short key!')
660
_realPass = self._decode_parameter(password)
661
_realSalt = self._decode_parameter(salt)
663
cdef unsigned char *_out = <unsigned char *>malloc(keyLen)
665
success = cmc.PKCS5_PBKDF2_HMAC_SHA1(_realPass, len(_realPass),
666
_realSalt, len(_realSalt),
670
bytes = _out[:keyLen]
313
#elif PY_MAJOR_VERSION == 2
314
# if callable(kdf) == False:
315
# raise ValueError('kdf must be callable')
316
#elif PY_MAJOR_VERSION == 3:
317
# if hasattr(kdf, '__call__') == False:
318
# raise ValueError('kdf must be callable')
321
msg = 'possibly insecure # of iterations'.format(iters)
322
warnings.warn(msg, McryptSecurityWarning)
323
self._kdf_iterations = iters
326
if len(_s2b(salt)) < 8:
327
msg = 'extremely short salt in use'
328
warnings.warn(msg, McryptSecurityWarning)
329
self._salt = _s2b(salt)
331
# is this secure/random enough?
332
self._salt = os.urandom(8)
335
if len(_s2b(iv)) != self._iv_len:
336
msg = 'iv must be {0} bytes exactly'
337
raise ValueError(msg.format(self._iv_len))
340
# is this secure/random enough?
341
self._iv = os.urandom(self._iv_len)
344
self._key_len = self._avail_key_sizes[-1]
345
elif klen in self._avail_key_sizes:
348
msg = 'klen must be one of {0}, not {1}'
349
raise ValueError(msg.format(self._avail_key_sizes,
352
self._key = kdf(_s2b(passwd), self._salt, self._kdf_iterations,
353
self._key_len, **kwargs)
355
def _close_mcrypt(self):
356
if self._mcStream is not NULL:
357
cmc.mcrypt_module_close(self._mcStream)
358
self._mcStream = NULL
362
'''Handles variable init at object instantiation time.'''
363
self._iv_len = cmc.mcrypt_enc_get_iv_size(self._mcStream)
364
self._block_size = cmc.mcrypt_enc_get_block_size(self._mcStream)
365
self._encdec_mode = 'none'
367
self._avail_key_sizes = []
369
cdef int array_length
371
keyszs = cmc.mcrypt_enc_get_supported_key_sizes(self._mcStream,
373
for i in range(array_length):
374
self._avail_key_sizes.append(keyszs[i])
379
def _open_mcrypt(self, algo, mode):
380
self._mcStream = cmc.mcrypt_module_open(algo, NULL,
382
if self._mcStream is NULL:
383
msg = 'mcrypt init failed: a:{0} m:{1}'
384
raise McryptError(msg.format(algo, mode))
387
cdef class raw_encrypt(_mcrypt_base):
388
'''raw_encrypt([algo[, mode]]) -> raw_encrypt object
389
A class for encrypting data using the mcrypt library.
391
This class provides encryption functionality to Python programs,
392
built on the mcrypt library. If unspecified, algo and mode will
393
be set to default values, which for this release is AES
394
(Rijndael-128) and CBC mode. These defaults may change in the
395
future, however. The algorithm and the mode can be set to one of
396
the constants defined in this module; see the module help for what
399
The encryption process provides a barebones encryption class; it
400
does nothing but convert from plaintext to ciphertext,
401
block-by-block. Extra functionality comes from classes derived
404
cdef int _blocks_processed
406
def __init__(self, algo = ALGO_DEFAULT, mode = MODE_DEFAULT):
407
super(raw_encrypt, self).__init__(algo, mode)
408
self._encdec_mode = 'encrypt'
413
Begins an encryption process.
415
The encryption process is a state machine: it is started,
416
stepped (presumably until the end of input) and then stopped
417
(whereupon it can be restarted with a different input if
418
desired). It is an error to call this method when an
419
encryption process is already running.'''
420
if self._running == True:
421
msg = 'attempt to start an already started encrypter'
422
raise McryptError(msg)
424
if len(self._iv) != self._iv_len:
425
raise McryptError('IV is incorrectly set.')
426
elif self._iv_len == 0:
427
cmc.mcrypt_generic_init(self._mcStream,
432
cmc.mcrypt_generic_init(self._mcStream,
437
self._blocks_processed = 0
443
Ends an encryption process.
445
After an encryption process is ended, a new one can be begin.
446
In effect, this is how object reuse is made possible. It is
447
an error to call this method when an encryption process is
449
if self._running == False:
450
msg = 'attempt to end an already ended encrypter'
451
raise McryptError(msg)
453
cmc.mcrypt_generic_deinit(self._mcStream)
456
def get_blocks_processed(self):
457
return self._blocks_processed
459
def step(self, input):
460
'''step(input) -> bytes
461
Runs a single step of the encryption process.
463
This function executes a single step of the encryption
464
process; that is, it will encrypt whatever blocks of data are
465
provided. The input data length must be exactly a multiple of
466
the current block size. An exception will be raised if the
467
data is incorrectly sized or if mcrypt returns an error.
469
The return value is the encrypted block.'''
470
if self._running == False:
471
msg = 'attempt to step nonrunning encrypter'
472
raise McryptError(msg)
476
if in_len % self._block_size > 0:
477
msg = 'input size must be an interval of block size {0}'
478
msg += '(e.g., size % {0} == 0 must be True)'
479
raise ValueError(msg.format(self._block_size))
481
cdef char* buffer = <char*>malloc(in_len)
482
cmc.strncpy(buffer, in_bin, in_len)
483
success = cmc.mcrypt_generic(self._mcStream, <void*>buffer, in_len)
487
msg = 'mcrypt returned error {0}: {1}'
488
raise McryptError(msg.format(success,
489
cmc.mcrypt_strerror(success)))
491
retval = buffer[:in_len]
494
self._blocks_processed += 1
497
cdef class raw_decrypt(_mcrypt_base):
498
'''raw_decrypt([algo[, mode]]) -> raw_decrypt object
499
A class for decrypting data using the mcrypt library.
501
This class provides decryption functionality to Python programs,
502
built on the mcrypt library. If unspecified, algo and mode will
503
be set to default values, which for this release is AES
504
(Rijndael-128) and CBC mode. These defaults may change in the
505
future, however. The algorithm and the mode can be set to one of
506
the constants defined in this module; see the module help for what
509
The decryption process provides a barebones decryption class. You
510
must know and set all parameters for decryption, they are not
511
automatically detected. This class just takes ciphertext blocks
512
and turns them into plaintext blocks.'''
514
cdef int _blocks_processed
516
def __init__(self, algo = ALGO_DEFAULT, mode = MODE_DEFAULT):
517
super(raw_decrypt, self).__init__(algo, mode)
518
self._encdec_mode = 'decrypt'
523
Begins a decryption process.
525
The decryption process is a state machine: it is started,
526
stepped (presumably until the end of input) and then stopped
527
(whereupon it can be restarted with a different input if
528
desired). It is an error to call this method when a
529
decryption process is already running.'''
530
if self._running == True:
531
msg = 'attempt to start an already started decrypter'
532
raise McryptError(msg)
534
if len(self._iv) != self._iv_len:
535
raise McryptError('IV is incorrectly set')
536
elif self._iv_len == 0:
537
cmc.mcrypt_generic_init(self._mcStream,
542
cmc.mcrypt_generic_init(self._mcStream,
547
self._blocks_processed = 0
553
Ends a decryption process.
555
After a decryption process is ended, a new one can be begin.
556
In effect, this is how object reuse is made possible. It is
557
an error to call this method when a decryption process is not
559
if self._running == False:
560
msg = 'attempt to end an already ended decrypter'
561
raise McryptError(msg)
563
cmc.mcrypt_generic_deinit(self._mcStream)
566
def step(self, input):
567
'''step(input) -> bytes
568
Runs a single step of the encryption process.
570
This function executes a single step of the encryption
571
process; that is, it will encrypt whatever blocks of data are
572
provided. The input data length must be exactly a multiple of
573
the current block size. An exception will be raised if the
574
data is incorrectly sized or if mcrypt returns an error.
576
The return value is the encrypted block.'''
577
if self._running == False:
578
msg = 'attempt to step nonrunning decrypter'
579
raise McryptError(msg)
583
if in_len % self._block_size > 0:
584
msg = 'input size must be an interval of block size {0}'
585
msg += '(e.g., size % {0} == 0 must be True)'
586
raise ValueError(msg.format(self._block_size))
588
cdef char* buffer = <char*>malloc(in_len)
589
cmc.strncpy(buffer, in_bin, in_len)
590
success = cmc.mdecrypt_generic(self._mcStream, <void*>buffer, in_len)
594
msg = 'mcrypt returned error {0}: {1}'
595
raise McryptError(msg.format(success,
596
cmc.mcrypt_strerror(success)))
598
retval = buffer[:in_len]
601
self._blocks_processed += 1