blob: 100041a7c2d1416b686d507438c3580dec2224f2 (
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
|
/**
* IVMode
*
* An abstract class for confidentialy modes that rely on an initialization vector.
* Copyright (c) 2007 Henri Torgemane
*
* See LICENSE.txt for full license information.
*/
package com.hurlant.crypto.symmetric
{
import com.hurlant.crypto.prng.Random;
import com.hurlant.crypto.tests.TestCase;
import com.hurlant.util.Memory;
import flash.utils.ByteArray;
/**
* An "abtract" class to avoid redundant code in subclasses
*/
public class IVMode
{
protected var key:ISymmetricKey;
protected var padding:IPad;
// random generator used to generate IVs
protected var prng:Random;
// optional static IV. used for testing only.
protected var iv:ByteArray;
// generated IV is stored here.
protected var lastIV:ByteArray;
protected var blockSize:uint;
public function IVMode(key:ISymmetricKey, padding:IPad = null) {
this.key = key;
blockSize = key.getBlockSize();
if (padding == null) {
padding = new PKCS5(blockSize);
} else {
padding.setBlockSize(blockSize);
}
this.padding = padding;
prng = new Random;
iv = null;
lastIV = new ByteArray;
}
public function getBlockSize():uint {
return key.getBlockSize();
}
public function dispose():void {
var i:uint;
if (iv != null) {
for (i=0;i<iv.length;i++) {
iv[i] = prng.nextByte();
}
iv.length=0;
iv = null;
}
if (lastIV != null) {
for (i=0;i<iv.length;i++) {
lastIV[i] = prng.nextByte();
}
lastIV.length=0;
lastIV=null;
}
key.dispose();
key = null;
padding = null;
prng.dispose();
prng = null;
Memory.gc();
}
/**
* Optional function to force the IV value.
* Normally, an IV gets generated randomly at every encrypt() call.
* Also, use this to set the IV before calling decrypt()
* (if not set before decrypt(), the IV is read from the beginning of the stream.)
*/
public function set IV(value:ByteArray):void {
iv = value;
lastIV.length=0;
lastIV.writeBytes(iv);
}
public function get IV():ByteArray {
return lastIV;
}
protected function getIV4e():ByteArray {
var vec:ByteArray = new ByteArray;
if (iv) {
vec.writeBytes(iv);
} else {
prng.nextBytes(vec, blockSize);
}
lastIV.length=0;
lastIV.writeBytes(vec);
return vec;
}
protected function getIV4d():ByteArray {
var vec:ByteArray = new ByteArray;
if (iv) {
vec.writeBytes(iv);
} else {
throw new Error("an IV must be set before calling decrypt()");
}
return vec;
}
}
}
|