luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 */