RSA.h (7454B)
1 /* 2 * RSA.h - RSA Public Key Cryptography Interface 3 * 4 * Compliant with: 5 * - PKCS#1 v1.5 (RSA Cryptography Standard) 6 * - FIPS 186-4 (Digital Signature Standard) 7 * 8 * Security Features: 9 * - RSA encryption/decryption 10 * - Digital signatures 11 * - PKCS#1 v1.5 padding 12 * - Secure random number generation 13 * 14 * WARNING: This is an educational implementation. 15 * For production use, consider: 16 * - OpenSSL, mbedTLS, or libsodium 17 * - 2048-bit or 4096-bit keys (not the demo's 32-bit) 18 * - OAEP padding for encryption 19 * - PSS padding for signatures 20 * - Proper key storage and management 21 */ 22 23 #ifndef RSA_H 24 #define RSA_H 25 26 #include <stdint.h> 27 #include <stdlib.h> 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /* Recommended key sizes (in bits) */ 34 #define RSA_KEY_SIZE_2048 2048 35 #define RSA_KEY_SIZE_3072 3072 36 #define RSA_KEY_SIZE_4096 4096 37 38 /* Common public exponent */ 39 #define RSA_EXPONENT_65537 65537 40 41 /* RSA public key structure */ 42 typedef struct { 43 uint8_t *n; /* Modulus (n = p * q) */ 44 size_t n_len; /* Modulus length in bytes */ 45 uint8_t *e; /* Public exponent (typically 65537) */ 46 size_t e_len; /* Exponent length in bytes */ 47 } rsa_public_key; 48 49 /* RSA private key structure (with CRT parameters for speed) */ 50 typedef struct { 51 uint8_t *n; /* Modulus */ 52 size_t n_len; 53 uint8_t *e; /* Public exponent */ 54 size_t e_len; 55 uint8_t *d; /* Private exponent (d = e^-1 mod φ(n)) */ 56 size_t d_len; 57 uint8_t *p; /* First prime factor */ 58 size_t p_len; 59 uint8_t *q; /* Second prime factor */ 60 size_t q_len; 61 uint8_t *dp; /* d mod (p-1) for CRT */ 62 size_t dp_len; 63 uint8_t *dq; /* d mod (q-1) for CRT */ 64 size_t dq_len; 65 uint8_t *qinv; /* q^-1 mod p for CRT */ 66 size_t qinv_len; 67 } rsa_private_key; 68 69 /** 70 * Generate RSA key pair (simplified implementation) 71 * 72 * @param pub Output public key 73 * @param priv Output private key 74 * @param bits Key size in bits (limited to 32 in simple mode) 75 * @return 0 on success, -1 on error 76 * 77 * Security Notes: 78 * - This simple implementation uses small keys for education only 79 * - For production: compile with -DUSE_GMP and use ≥2048 bits 80 * - Keys must be protected in memory and storage 81 * - Private key must be kept secret 82 */ 83 int rsa_generate_key_simple(rsa_public_key *pub, rsa_private_key *priv, int bits); 84 85 /** 86 * RSA Encryption with PKCS#1 v1.5 padding 87 * 88 * @param key Public key 89 * @param plaintext Input data 90 * @param pt_len Plaintext length (must be ≤ key_size - 11 bytes) 91 * @param ciphertext Output buffer (must be key_size bytes) 92 * @param ct_len Output ciphertext length 93 * @return 0 on success, -1 on error 94 * 95 * Security Notes: 96 * - Maximum plaintext length: key_size_bytes - 11 97 * - For 2048-bit key: max 245 bytes plaintext 98 * - PKCS#1 v1.5 has known weaknesses, prefer OAEP 99 * - Use hybrid encryption for large messages (RSA + AES) 100 */ 101 int rsa_encrypt(const rsa_public_key *key, 102 const uint8_t *plaintext, size_t pt_len, 103 uint8_t *ciphertext, size_t *ct_len); 104 105 /** 106 * RSA Decryption with PKCS#1 v1.5 padding 107 * 108 * @param key Private key 109 * @param ciphertext Input ciphertext (key_size bytes) 110 * @param ct_len Ciphertext length 111 * @param plaintext Output buffer 112 * @param pt_len Output plaintext length 113 * @return 0 on success, -1 on error 114 * 115 * Security Notes: 116 * - Validates padding format 117 * - Returns error on invalid padding 118 * - Timing attacks possible with PKCS#1 v1.5 119 * - Prefer OAEP for new applications 120 */ 121 int rsa_decrypt(const rsa_private_key *key, 122 const uint8_t *ciphertext, size_t ct_len, 123 uint8_t *plaintext, size_t *pt_len); 124 125 /** 126 * RSA Sign with PKCS#1 v1.5 padding 127 * 128 * @param key Private key 129 * @param message Message digest (typically SHA-256 hash) 130 * @param msg_len Message digest length 131 * @param signature Output signature buffer (key_size bytes) 132 * @param sig_len Output signature length 133 * @return 0 on success, -1 on error 134 * 135 * Security Notes: 136 * - Message should be a hash digest (SHA-256, SHA-512) 137 * - Do NOT sign raw messages, hash them first 138 * - Maximum message length: key_size_bytes - 11 139 * - Prefer PSS padding for new applications 140 */ 141 int rsa_sign(const rsa_private_key *key, 142 const uint8_t *message, size_t msg_len, 143 uint8_t *signature, size_t *sig_len); 144 145 /** 146 * RSA Verify signature 147 * 148 * @param key Public key 149 * @param message Message digest that was signed 150 * @param msg_len Message digest length 151 * @param signature Signature to verify 152 * @param sig_len Signature length 153 * @return 0 if valid, -1 if invalid 154 * 155 * Security Notes: 156 * - Message must be the same hash used in signing 157 * - Validates padding and message match 158 * - Returns -1 for any verification failure 159 */ 160 int rsa_verify(const rsa_public_key *key, 161 const uint8_t *message, size_t msg_len, 162 const uint8_t *signature, size_t sig_len); 163 164 /** 165 * RSA Sign with PSS (Probabilistic Signature Scheme) padding 166 * 167 * @param key Private key 168 * @param message Message digest (typically SHA-256 hash) 169 * @param msg_len Message digest length (must be 32 for SHA-256) 170 * @param signature Output signature buffer (key_size bytes) 171 * @param sig_len Output signature length 172 * @return 0 on success, -1 on error 173 * 174 * Security Notes: 175 * - PSS is more secure than PKCS#1 v1.5 176 * - Preferred for TLS 1.3 and modern applications 177 * - Uses SHA-256 as hash function and MGF1 178 * - Message should be a hash digest (SHA-256 recommended) 179 */ 180 int rsa_sign_pss(const rsa_private_key *key, 181 const uint8_t *message, size_t msg_len, 182 uint8_t *signature, size_t *sig_len); 183 184 /** 185 * RSA Verify PSS signature 186 * 187 * @param key Public key 188 * @param message Message digest that was signed 189 * @param msg_len Message digest length 190 * @param signature Signature to verify 191 * @param sig_len Signature length 192 * @return 0 if valid, -1 if invalid 193 * 194 * Security Notes: 195 * - Verifies PSS padding per RFC 8017 196 * - Uses SHA-256 as hash function and MGF1 197 * - Returns -1 for any verification failure 198 */ 199 int rsa_verify_pss(const rsa_public_key *key, 200 const uint8_t *message, size_t msg_len, 201 const uint8_t *signature, size_t sig_len); 202 203 /** 204 * Free RSA public key 205 * 206 * @param key Public key to free 207 * 208 * Security: Zeros memory before freeing 209 */ 210 void rsa_free_public_key(rsa_public_key *key); 211 212 /** 213 * Free RSA private key 214 * 215 * @param key Private key to free 216 * 217 * Security: Zeros all sensitive data before freeing 218 * CRITICAL: Always call this for private keys 219 */ 220 void rsa_free_private_key(rsa_private_key *key); 221 222 /** 223 * Print public key in hex format 224 * 225 * @param key Public key to print 226 */ 227 void rsa_print_public_key(const rsa_public_key *key); 228 229 /** 230 * Export public key to buffer (DER format - future implementation) 231 * 232 * @param key Public key 233 * @param buffer Output buffer 234 * @param buf_len Buffer length 235 * @return Bytes written, or -1 on error 236 */ 237 int rsa_export_public_key(const rsa_public_key *key, 238 uint8_t *buffer, size_t buf_len); 239 240 /** 241 * Import public key from buffer (DER format - future implementation) 242 * 243 * @param key Output public key 244 * @param buffer Input buffer 245 * @param buf_len Buffer length 246 * @return 0 on success, -1 on error 247 */ 248 int rsa_import_public_key(rsa_public_key *key, 249 const uint8_t *buffer, size_t buf_len); 250 251 #ifdef __cplusplus 252 } 253 #endif 254 255 #endif /* RSA_H */