File: Reviewing.md

package info (click to toggle)
haskell-raaz 0.2.0-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 844 kB
  • sloc: haskell: 5,045; ansic: 1,885; makefile: 18
file content (132 lines) | stat: -rw-r--r-- 3,547 bytes parent folder | download | duplicates (2)
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
# Checklist for reviewing code.

## Reviewing Haskell code

### Timing safe equality.

All cryptographically sensitive data types should have timing safe
equality comparison. The class `Equality` is the timing safe
counterpart of the `Eq` class. All such sensitive types should define
the `Equality` instance first using the `eq` and the monoid instance
of the `Result` type. The `Eq` type should then be a simple use of
`(===)`.

Good example.

```haskell

data GoodSensitiveType = ...

instance Equality GoodSensitiveType where
	eq a b = ...

instance Eq GoodSensitiveType where
	(==) = (===)

```

Here are some other example of a good definition.

```haskell

-- makes use of the Equality instance for pair.
newtype AnotherGoodType = AGT (Foo,Bar) deriving Equality

instance Eq AnotherGoodType where
	(==) = (===)

-- | Makes use of the Equality and Eq instances of tuple types.
newtype Foo = Foo (Tuple 42 Word32) deriving (Equality, Eq)


```

A bad example. The deriving clause makes the (==) timing dependent
even if `Foo` and `Bar` have timing safe equality.

```haskell
data BadSensitiveType = BadSensitiveType Foo Bar deriving Eq

```


### Dangerous modules

We document here some of the Haskell modules that do dangerous stuff
so that they can be audited more carefully. The exact dangers are
documented in the module.


1. Raaz.Cipher.ChaCha20.Recommendation.

2. Raaz.Cipher.ChaCha20.Implementation.CPortable


## Reviewing C code.

For speed, the block primitives are written in C. Most primitives have
a default word type (64-bit unsigned int for `sha512` for
example). They also have a block that is essentially an array of such
words (for `sha512` it is 16. So it will be common to see declarations
of the following kind.

```C

typedef uint64_t   Word;  /* basic unit of sha512 hash  */
#define HASH_SIZE  8      /* Number of words in a Hash  */
#define BLOCK_SIZE 16     /* Number of words in a block */

typedef Word Hash [ HASH_SIZE  ];
typedef Word Block[ BLOCK_SIZE ];

```

In such a setting, we often have a loop that goes over all the
blocks. This would typically look like the following.

```C

void foo(Block *ptr, int nblocks, ...)
{
	/* Other stuff here */

	while(nblocks > 0) /* looping over all blocks */
	{

       doSomethingOn((*ptr)[i]); /* do something on the ith word in the current block */

       -- nblocks; ++ ptr; /* move to the next block ensure these are
                            * on the same line
	                        */

	}
}

```

We would like to follow the above convention be cause it reduces the
chance of incorrect pointer arithmetic. The bugs are concentrated on
the definition of the block and word types. So if one is reviewing
such low level code, it is better to get familiarised with this
programming pattern.


## Stuff that effects both C and Haskell.

## Alignment and restrict for block primitives

GCC can perform brutal optimisations even to Portable C
implementations if the right argument is qualified with restrict and
the alignment is matched to the associated vector operations. But these
features are Dangerous

1. Make sure that the alignment that you provide at the Haskell end
   when you define the Implementation is the same as (or a multiple
   of) that at the C side.

2. Since we expect to call these functions as an ffi it is relatively
   safe to assume that the buffer is not aliased. So restrict can also
   be given.

Be careful with ChaCha20 implementation where the alignment is also
used for the PRG buffer (See the dangerous modules subsection).