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 32struct clHASH_CTX; // forward decl. 33 34// RSA interface ---------------------------------------- 35 36typedef 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. 47int 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 54typedef 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 63typedef 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 78typedef 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) 85const uint8_t* clHMAC_final(clHMAC_CTX* ctx); 86 87// SHA1 interface ---------------------------------------------- 88 89#define clSHA1_DIGEST_SIZE 20 90typedef clHASH_CTX clSHA1_CTX; 91 92void clSHA1_init(clSHA1_CTX* ctx); 93void clHMAC_SHA1_init(clHMAC_CTX* ctx, const void* key, int len); 94const uint8_t* clSHA1(const void* data, int len, uint8_t* digest); 95 96// SHA256 interface -------------------------------------------- 97 98#define clSHA256_DIGEST_SIZE 32 99typedef clHASH_CTX clSHA256_CTX; 100 101void clSHA256_init(clSHA256_CTX* ctx); 102void clHMAC_SHA256_init(clHMAC_CTX* ctx, const void* key, int len); 103const 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! 109int 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). 116int 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). 123int 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 130typedef struct clPRNG_CTX { 131 uint8_t v[clSHA256_DIGEST_SIZE * 2]; 132 int index; 133} clPRNG_CTX; 134 135// Initial seeding. 136void 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(). 140void 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. 144void clPRNG_draw(clPRNG_CTX* ctx, void* out, int size); 145 146__END_CDECLS 147