Added cipher wrapper functions
[people/xl0/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, void *key, size_t keylen );
37         /** Encode data
38          *
39          * @v ctx               Context
40          * @v src               Data to encode
41          * @v dst               Encoded data, or NULL
42          * @v len               Length of data
43          * @ret rc              Return status code
44          *
45          * For a cipher algorithm, the enciphered data should be
46          * placed in @c dst.  For a digest algorithm, only the digest
47          * state should be updated, and @c dst will be NULL.
48          *
49          * @v len is guaranteed to be a multiple of @c blocksize.
50          */
51         void ( * encode ) ( void *ctx, const void *src, void *dst,
52                             size_t len );
53         /** Decode data
54          *
55          * @v ctx               Context
56          * @v src               Data to decode
57          * @v dst               Decoded data
58          * @v len               Length of data
59          * @ret rc              Return status code
60          *
61          * @v len is guaranteed to be a multiple of @c blocksize.
62          */
63         void ( * decode ) ( void *ctx, const void *src, void *dst,
64                             size_t len );
65         /** Finalise algorithm
66          *
67          * @v ctx               Context
68          * @v out               Algorithm final output
69          */
70         void ( * final ) ( void *ctx, void *out );
71 };
72
73 static inline void digest_init ( struct crypto_algorithm *crypto,
74                                  void *ctx ) {
75         crypto->init ( ctx );
76 }
77
78 static inline void digest_update ( struct crypto_algorithm *crypto,
79                                    void *ctx, const void *data, size_t len ) {
80         crypto->encode ( ctx, data, NULL, len );
81 }
82
83 static inline void digest_final ( struct crypto_algorithm *crypto,
84                                   void *ctx, void *out ) {
85         crypto->final ( ctx, out );
86 }
87
88 static inline int cipher_encrypt ( struct crypto_algorithm *crypto,
89                                    void *ctx, const void *src, void *dst,
90                                    size_t len ) {
91         if ( ( len & ( crypto->blocksize - 1 ) ) ) {
92                 return -EINVAL;
93         }
94         crypto->encode ( ctx, src, dst, len );
95         return 0;
96 }
97
98 static inline int cipher_decrypt ( struct crypto_algorithm *crypto,
99                                    void *ctx, const void *src, void *dst,
100                                    size_t len ) {
101         if ( ( len & ( crypto->blocksize - 1 ) ) ) {
102                 return -EINVAL;
103         }
104         crypto->decode ( ctx, src, dst, len );
105         return 0;
106 }
107
108 static inline int is_stream_cipher ( struct crypto_algorithm *crypto ) {
109         return ( crypto->blocksize == 1 );
110 }
111
112 #endif /* _GPXE_CRYPTO_H */