1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Author: Marius Schilder
16 //
17 // Lightweight C crypto library for sha256, hmac-sha256, DH,
18 // RSA2K-SHA256-PKCS15, PRNG, sha1, hmac-sha1, RSA2K-SHA1-PKCS15.
19 //
20 // Plain C, no system calls, no malloc.
21 
22 #pragma once
23 
24 #include <inttypes.h>
25 #include <zircon/compiler.h>
26 
27 #define clBIGNUMBYTES 256      // 2048 bit key length max
28 #define clBIGNUMWORDS (clBIGNUMBYTES / sizeof(uint32_t))
29 
30 __BEGIN_CDECLS
31 
32 struct clHASH_CTX;  // forward decl.
33 
34 // RSA interface ----------------------------------------
35 
36 typedef struct clBignumModulus {
37   int size;                    // Length of n[] in bytes;
38   int nwords;                  // Length of n[] in number of uint32_t
39   uint32_t n0inv;              // -1 / n[0] mod 2^32
40   uint32_t n[clBIGNUMWORDS];   // modulus as little endian array
41   uint32_t rr[clBIGNUMWORDS];  // 2^(2*32*nwords) mod n as little endian array
42 } clBignumModulus;
43 
44 // PKCS1.5 signature verify.
45 // signature_len must be key->size.
46 // Returns 1 if OK. Trashes hash.
47 int clRSA2K_verify(const clBignumModulus* key,
48                    const uint8_t* signature,
49                    const int signature_len,
50                    struct clHASH_CTX* hash /* not const! */);
51 
52 // Generic hash interface ----------------------------------------
53 
54 typedef struct clHASH_vtab {
55   void (* const init)(struct clHASH_CTX*);
56   void (* const update)(struct clHASH_CTX*, const void*, int);
57   const uint8_t* (* const final)(struct clHASH_CTX*);
58   void (* const _transform)(struct clHASH_CTX*);
59   const int size;
60   const uint8_t* _2Kpkcs15hashpad;  // hash of 2K bit padding.
61 } clHASH_vtab;
62 
63 typedef struct clHASH_CTX {
64   const clHASH_vtab* f;
65   uint64_t count;
66   uint8_t buf[64];
67   uint32_t state[8];
68 } clHASH_CTX;
69 
70 #define clHASH_init(ctx) (ctx)->f->init(ctx)
71 #define clHASH_update(ctx, data, len) (ctx)->f->update(ctx, data, len)
72 #define clHASH_final(ctx) (ctx)->f->final(ctx)
73 #define clHASH_size(ctx) (ctx)->f->size
74 #define clHASH_MAX_DIGEST_SIZE 32
75 
76 // Generic hmac interface ----------------------------------------
77 
78 typedef struct clHMAC_CTX {
79   clHASH_CTX hash;
80   uint8_t opad[64];
81 } clHMAC_CTX;
82 
83 #define clHMAC_update(ctx, data, len) clHASH_update(&(ctx)->hash, data, len)
84 #define clHMAC_size(ctx) clHASH_size(&(ctx)->hash)
85 const uint8_t* clHMAC_final(clHMAC_CTX* ctx);
86 
87 // SHA1 interface ----------------------------------------------
88 
89 #define clSHA1_DIGEST_SIZE 20
90 typedef clHASH_CTX clSHA1_CTX;
91 
92 void clSHA1_init(clSHA1_CTX* ctx);
93 void clHMAC_SHA1_init(clHMAC_CTX* ctx, const void* key, int len);
94 const uint8_t* clSHA1(const void* data, int len, uint8_t* digest);
95 
96 // SHA256 interface --------------------------------------------
97 
98 #define clSHA256_DIGEST_SIZE 32
99 typedef clHASH_CTX clSHA256_CTX;
100 
101 void clSHA256_init(clSHA256_CTX* ctx);
102 void clHMAC_SHA256_init(clHMAC_CTX* ctx, const void* key, int len);
103 const uint8_t* clSHA256(const void* data, int len, uint8_t* digest);
104 
105 // Safe compare interface --------------------------------
106 
107 // Returns 0 if equal.
108 // Only fixed timing if arrays are of same length!
109 int clEqual(const uint8_t* a, int a_len, const uint8_t* b, int b_len);
110 
111 // DH interface --------------------------------------------
112 
113 // Computes 2 ** x into out. x and out bigendian byte strings.
114 // out must be able to hold mod->size bytes.
115 // Return 0 on error. (invalid value for x).
116 int clDHgenerate(const clBignumModulus* mod,
117                  const uint8_t* x, const int size_x,
118                  uint8_t* out);
119 
120 // Computes gy ** x into out. gy, x, and out bigendian byte strings.
121 // size_gy must be mod->size.
122 // Returns 0 on error. (invalid size_gy, gy, x).
123 int clDHcompute(const clBignumModulus* mod,
124                 const uint8_t* gy, const int size_gy,
125                 const uint8_t* x, const int size_x,
126                 uint8_t* out);
127 
128 // PRNG interface --------------------------------------------
129 
130 typedef struct clPRNG_CTX {
131   uint8_t v[clSHA256_DIGEST_SIZE * 2];
132   int index;
133 } clPRNG_CTX;
134 
135 // Initial seeding.
136 void clPRNG_init(clPRNG_CTX* ctx, const void* data, int size);
137 
138 // Add entropy to state. Non-destructive, additive.
139 // Best to call at least once before calling clPRNG_draw().
140 void clPRNG_entropy(clPRNG_CTX* ctx, const void* data, int size);
141 
142 // Generate size bytes random and advance state.
143 // Beware: out value covers entire spectrum so all 0 is possible.
144 void clPRNG_draw(clPRNG_CTX* ctx, void* out, int size);
145 
146 __END_CDECLS
147