fc1f50bc5ef2d23b6ac7d6ff320699699f22bcbf
[people/holger/gpxe.git] / src / include / gpxe / crypto.h
1 #ifndef _GPXE_CRYPTO_H
2 #define _GPXE_CRYPTO_H
3
4 /** @file
5  *
6  * Cryptographic API
7  *
8  */
9
10 #include <stdint.h>
11 #include <stddef.h>
12 #include <errno.h>
13
14 /** A cryptographic algorithm */
15 struct crypto_algorithm {
16         /** Algorithm name */
17         const char *name;
18         /** Context size */
19         size_t ctxsize;
20         /** Block size */
21         size_t blocksize;
22         /** Final output size */
23         size_t digestsize;
24         /** Initialise algorithm
25          *
26          * @v ctx               Context
27          */
28         void ( * init ) ( void *ctx );
29         /** Set key
30          *
31          * @v ctx               Context
32          * @v key               Key
33          * @v keylen            Key length
34          * @ret rc              Return status code
35          */
36         int ( * setkey ) ( void *ctx, const void *key, size_t keylen );
37         /** Set initialisation vector
38          *
39          * @v ctx               Context
40          * @v iv                Initialisation vector
41          */
42         void ( *setiv ) ( void *ctx, const void *iv );
43         /** Encode data
44          *
45          * @v ctx               Context
46          * @v src               Data to encode
47          * @v dst               Encoded data, or NULL
48          * @v len               Length of data
49          * @ret rc              Return status code
50          *
51          * For a cipher algorithm, the enciphered data should be
52          * placed in @c dst.  For a digest algorithm, only the digest
53          * state should be updated, and @c dst will be NULL.
54          *
55          * @v len is guaranteed to be a multiple of @c blocksize.
56          */
57         void ( * encode ) ( void *ctx, const void *src, void *dst,
58                             size_t len );
59         /** Decode data
60          *
61          * @v ctx               Context
62          * @v src               Data to decode
63          * @v dst               Decoded data
64          * @v len               Length of data
65          * @ret rc              Return status code
66          *
67          * @v len is guaranteed to be a multiple of @c blocksize.
68          */
69         void ( * decode ) ( void *ctx, const void *src, void *dst,
70                             size_t len );
71         /** Finalise algorithm
72          *
73          * @v ctx               Context
74          * @v out               Algorithm final output
75          */
76         void ( * final ) ( void *ctx, void *out );
77 };
78
79 static inline void digest_init ( struct crypto_algorithm *crypto,
80                                  void *ctx ) {
81         crypto->init ( ctx );
82 }
83
84 static inline void digest_update ( struct crypto_algorithm *crypto,
85                                    void *ctx, const void *data, size_t len ) {
86         crypto->encode ( ctx, data, NULL, len );
87 }
88
89 static inline void digest_final ( struct crypto_algorithm *crypto,
90                                   void *ctx, void *out ) {
91         crypto->final ( ctx, out );
92 }
93
94 static inline void cipher_setiv ( struct crypto_algorithm *crypto,
95                                   void *ctx, const void *iv ) {
96         crypto->setiv ( ctx, iv );
97 }
98
99 static inline int cipher_setkey ( struct crypto_algorithm *crypto,
100                                   void *ctx, const void *key, size_t keylen ) {
101         return crypto->setkey ( ctx, key, keylen );
102 }
103
104 static inline int cipher_encrypt ( struct crypto_algorithm *crypto,
105                                    void *ctx, const void *src, void *dst,
106                                    size_t len ) {
107         if ( ( len & ( crypto->blocksize - 1 ) ) ) {
108                 return -EINVAL;
109         }
110         crypto->encode ( ctx, src, dst, len );
111         return 0;
112 }
113
114 static inline int cipher_decrypt ( struct crypto_algorithm *crypto,
115                                    void *ctx, const void *src, void *dst,
116                                    size_t len ) {
117         if ( ( len & ( crypto->blocksize - 1 ) ) ) {
118                 return -EINVAL;
119         }
120         crypto->decode ( ctx, src, dst, len );
121         return 0;
122 }
123
124 static inline int is_stream_cipher ( struct crypto_algorithm *crypto ) {
125         return ( crypto->blocksize == 1 );
126 }
127
128 extern struct crypto_algorithm crypto_null;
129
130 #endif /* _GPXE_CRYPTO_H */