[PR #270] [MERGED] Core/SSL: Secure Functions for Cryptographic Random/Nonce Generation #279

Closed
opened 2026-05-05 03:44:39 -06:00 by gitea-mirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/ultimatepp/ultimatepp/pull/270
Author: @ismail-yilmaz
Created: 5/18/2025
Status: Merged
Merged: 4/25/2026
Merged by: @mirek-fidler

Base: masterHead: rgen


📝 Commits (1)

  • 9863d3c Core/SSL: Secure random and nonce generator with SecureBuffer support

📊 Changes

6 files changed (+476 additions, -0 deletions)

View changed files

autotest/SecureRandomGenerator/SecureRandomGenerator.cpp (+233 -0)
autotest/SecureRandomGenerator/SecureRandomGenerator.upp (+10 -0)
uppsrc/Core/SSL/Random.cpp (+146 -0)
📝 uppsrc/Core/SSL/SSL.h (+17 -0)
📝 uppsrc/Core/SSL/SSL.upp (+1 -0)
uppsrc/Core/SSL/src.tpp/Upp_SSL_Random_en-us.tpp (+69 -0)

📄 Description

Rationale

U++ currently lacks a dedicated cryptographically secure nonce generator suitable for modern cryptographic protocols. This pull request introduces thread-safe nonce generation functions to the Core/SSL package, providing guaranteed uniqueness and fork-safety for cryptographic operations.

Features

  • Guaranteed uniqueness through process-unique identifiers and atomic counters
  • Cryptographic randomness via OpenSSL's CSPRNG
  • Fork-safe on POSIX systems with automatic state regeneration
  • Two generation modes:
    • Structured nonces (process UID + counter + optional random tail)
    • Pure cryptographic randomness
  • Standard-compliant sizes for common protocols (AES-GCM, ChaCha20-Poly1305, JWT, OCSP)
  • Thread-safe through lock-free atomic operations and lightweight SpinLock
  • Type-safe return values using SecureBuffer<byte> with automatic memory zeroing

Implementation Details

The generator combines three entropy sources:

  1. Process-unique identifier (64-bit CSPRNG-generated UID)
  2. Atomic counter with overflow protection
  3. OpenSSL CSPRNG for random tail padding

Nonce structure adapts based on size:

  • 12-15 bytes: [4B UID | 8B counter | random tail]
  • 16+ bytes: [8B UID | 8B counter | random tail]

Public API

// Core functions
SecureBuffer<byte> SecureRandom(int n);  // Pure CSPRNG output
SecureBuffer<byte> SecureNonce(int n);   // Structured nonce (min 12 bytes)

// Protocol-specific helpers
SecureBuffer<byte> GetAESGCMNonce();           // 12 bytes, AES-GCM/ChaCha20-Poly1305
SecureBuffer<byte> GetChaChaPoly1305Nonce();   // 12 bytes, alias for AES-GCM
SecureBuffer<byte> GetTLSNonce();              // 12 bytes, TLS 1.2/1.3
SecureBuffer<byte> GetAESCCMNonce();           // 13 bytes, AES-CCM
SecureBuffer<byte> GetJWTNonce();              // 16 bytes, JWT tokens
SecureBuffer<byte> GetOAuthNonce();            // 16 bytes, OAuth flows
SecureBuffer<byte> GetOCSPNonce();             // 20 bytes, OCSP requests
SecureBuffer<byte> GetECDSANonce();            // 32 bytes, ECDSA signatures
SecureBuffer<byte> GetDTLSCookie();            // 32 bytes, DTLS cookies

Security Properties

Property Guarantee
Uniqueness (same process) 2^64 (atomic counter ensures no reuse)
Uniqueness (cross-process) 2^64 (random UID collision probability)
Randomness Quality OpenSSL CSPRNG (platform-native)
Thread Safety Lock-free atomics + SpinLock for fork handling
Fork Safety Automatic UID/counter regeneration
Standards Compliance NIST SP 800-38D (12-byte minimum for AES-GCM)

Unit Tests

Comprehensive test suite with 13 test cases:

  • Basic functionality and size enforcement
  • Error handling for invalid inputs
  • Single-threaded uniqueness (1000 nonces)
  • Multi-threaded uniqueness (100K nonces × CPU cores)
  • Internal structure verification for both layouts
  • Cryptographic entropy validation (chi-square test)
  • Concurrent stress test (16 threads × 10K nonces)
  • All helper functions return correct sizes

Example Usage

// AES-GCM encryption
auto iv = GetAESGCMNonce();  // 12 bytes
cipher.SetIV(~iv, iv.GetSize());

// JWT token generation  
auto nonce = GetJWTNonce();  // 16 bytes
String token = Base64Encode(~nonce, nonce.GetSize());

// Direct CSPRNG access for key material
auto key = SecureRandom(32);  // 32 bytes of pure randomness

// Custom nonce size
auto custom = SecureNonce(24);  // [8B UID | 8B counter | 8B random]

Fixes or Enhances

  • Provides cryptographic primitives for existing SSL/TLS functionality
  • Enables secure implementation of modern AEAD ciphers (AES-GCM, ChaCha20-Poly1305)
  • Foundation for future JWT/OAuth support

Tested on

  • Windows 10/11 (MSVC, MinGW)
  • Linux (GCC, Clang)
  • OpenSSL 1.0.x, 1.1.x, 3.x

This addresses cryptographic primitive needs discussed in:


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/ultimatepp/ultimatepp/pull/270 **Author:** [@ismail-yilmaz](https://github.com/ismail-yilmaz) **Created:** 5/18/2025 **Status:** ✅ Merged **Merged:** 4/25/2026 **Merged by:** [@mirek-fidler](https://github.com/mirek-fidler) **Base:** `master` ← **Head:** `rgen` --- ### 📝 Commits (1) - [`9863d3c`](https://github.com/ultimatepp/ultimatepp/commit/9863d3c3194cc79b75dd8d40dc1747bb675ab5b5) Core/SSL: Secure random and nonce generator with SecureBuffer support ### 📊 Changes **6 files changed** (+476 additions, -0 deletions) <details> <summary>View changed files</summary> ➕ `autotest/SecureRandomGenerator/SecureRandomGenerator.cpp` (+233 -0) ➕ `autotest/SecureRandomGenerator/SecureRandomGenerator.upp` (+10 -0) ➕ `uppsrc/Core/SSL/Random.cpp` (+146 -0) 📝 `uppsrc/Core/SSL/SSL.h` (+17 -0) 📝 `uppsrc/Core/SSL/SSL.upp` (+1 -0) ➕ `uppsrc/Core/SSL/src.tpp/Upp_SSL_Random_en-us.tpp` (+69 -0) </details> ### 📄 Description ## Rationale U++ currently lacks a dedicated cryptographically secure nonce generator suitable for modern cryptographic protocols. This pull request introduces thread-safe nonce generation functions to the `Core/SSL` package, providing guaranteed uniqueness and fork-safety for cryptographic operations. ## Features * **Guaranteed uniqueness** through process-unique identifiers and atomic counters * **Cryptographic randomness** via OpenSSL's CSPRNG * **Fork-safe** on POSIX systems with automatic state regeneration * **Two generation modes**: - Structured nonces (process UID + counter + optional random tail) - Pure cryptographic randomness * **Standard-compliant** sizes for common protocols (AES-GCM, ChaCha20-Poly1305, JWT, OCSP) * **Thread-safe** through lock-free atomic operations and lightweight SpinLock * **Type-safe** return values using `SecureBuffer<byte>` with automatic memory zeroing ## Implementation Details The generator combines three entropy sources: 1. **Process-unique identifier** (64-bit CSPRNG-generated UID) 2. **Atomic counter** with overflow protection 3. **OpenSSL CSPRNG** for random tail padding Nonce structure adapts based on size: - **12-15 bytes**: `[4B UID | 8B counter | random tail]` - **16+ bytes**: `[8B UID | 8B counter | random tail]` ## Public API ```cpp // Core functions SecureBuffer<byte> SecureRandom(int n); // Pure CSPRNG output SecureBuffer<byte> SecureNonce(int n); // Structured nonce (min 12 bytes) // Protocol-specific helpers SecureBuffer<byte> GetAESGCMNonce(); // 12 bytes, AES-GCM/ChaCha20-Poly1305 SecureBuffer<byte> GetChaChaPoly1305Nonce(); // 12 bytes, alias for AES-GCM SecureBuffer<byte> GetTLSNonce(); // 12 bytes, TLS 1.2/1.3 SecureBuffer<byte> GetAESCCMNonce(); // 13 bytes, AES-CCM SecureBuffer<byte> GetJWTNonce(); // 16 bytes, JWT tokens SecureBuffer<byte> GetOAuthNonce(); // 16 bytes, OAuth flows SecureBuffer<byte> GetOCSPNonce(); // 20 bytes, OCSP requests SecureBuffer<byte> GetECDSANonce(); // 32 bytes, ECDSA signatures SecureBuffer<byte> GetDTLSCookie(); // 32 bytes, DTLS cookies ``` ## Security Properties | Property | Guarantee | |------------------------|----------------------------------------------| | Uniqueness (same process) | 2^64 (atomic counter ensures no reuse) | | Uniqueness (cross-process) | 2^64 (random UID collision probability) | | Randomness Quality | OpenSSL CSPRNG (platform-native) | | Thread Safety | Lock-free atomics + SpinLock for fork handling | | Fork Safety | Automatic UID/counter regeneration | | Standards Compliance | NIST SP 800-38D (12-byte minimum for AES-GCM) | ## Unit Tests Comprehensive test suite with 13 test cases: * Basic functionality and size enforcement * Error handling for invalid inputs * Single-threaded uniqueness (1000 nonces) * Multi-threaded uniqueness (100K nonces × CPU cores) * Internal structure verification for both layouts * Cryptographic entropy validation (chi-square test) * Concurrent stress test (16 threads × 10K nonces) * All helper functions return correct sizes ## Example Usage ```cpp // AES-GCM encryption auto iv = GetAESGCMNonce(); // 12 bytes cipher.SetIV(~iv, iv.GetSize()); // JWT token generation auto nonce = GetJWTNonce(); // 16 bytes String token = Base64Encode(~nonce, nonce.GetSize()); // Direct CSPRNG access for key material auto key = SecureRandom(32); // 32 bytes of pure randomness // Custom nonce size auto custom = SecureNonce(24); // [8B UID | 8B counter | 8B random] ``` ## Fixes or Enhances - Provides cryptographic primitives for existing SSL/TLS functionality - Enables secure implementation of modern AEAD ciphers (AES-GCM, ChaCha20-Poly1305) - Foundation for future JWT/OAuth support ## Tested on - Windows 10/11 (MSVC, MinGW) - Linux (GCC, Clang) - OpenSSL 1.0.x, 1.1.x, 3.x ## Related Discussions This addresses cryptographic primitive needs discussed in: - [U++ Discussion #265](https://github.com/ultimatepp/ultimatepp/discussions/265) - [U++ Issue #266](https://github.com/ultimatepp/ultimatepp/issues/266) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
gitea-mirror 2026-05-05 03:44:39 -06:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/ultimatepp#279
No description provided.