From 3ccdfcbc5695d032f7f0a5c0bcfa8b85be965d5a Mon Sep 17 00:00:00 2001 From: Aleksei Fedorov Date: Fri, 13 Mar 2026 18:45:15 +0000 Subject: [PATCH] linux crypto subsystem --- app.py | 13 ++- index.html | 6 +- static/js/crypto-belt.js | 97 ++++++++++++++-- static/js/main.js | 6 +- static/js/right-semicircle-menu.js | 6 +- templates/linux-crypto-subsystem.html | 158 ++++++++++++++++++++++++++ 6 files changed, 263 insertions(+), 23 deletions(-) create mode 100644 templates/linux-crypto-subsystem.html diff --git a/app.py b/app.py index d17be29..6d8757d 100644 --- a/app.py +++ b/app.py @@ -16,7 +16,7 @@ import shutil from datetime import datetime from threading import Lock -from flask import Flask, jsonify, render_template, send_from_directory, request +from flask import Flask, jsonify, render_template, send_from_directory, request, redirect import psutil # Try to import OpenAI (optional) @@ -708,10 +708,15 @@ def index(): # Serve index.html from root directory return send_from_directory('.', 'index.html') +@app.route('/linux-crypto-subsystem') +def linux_crypto_subsystem_page(): + """SEO-friendly Linux crypto subsystem page.""" + return render_template('linux-crypto-subsystem.html') + @app.route('/crypto') -def crypto_page(): - """SEO-friendly crypto subsystem page.""" - return render_template('crypto.html') +def crypto_page_legacy(): + """Legacy path redirect to Linux crypto subsystem page.""" + return redirect('/linux-crypto-subsystem', code=301) @app.route('/api/syscalls-realtime') def syscalls_realtime(): diff --git a/index.html b/index.html index ef2843c..20a079c 100755 --- a/index.html +++ b/index.html @@ -96,11 +96,11 @@

Linux Kernel Ring 0 Visualization

- + - + @@ -121,6 +121,6 @@

Linux Kernel Ring 0 Visualization

// console.error('❌ Proc3DVisualization class NOT loaded!'); // } - + diff --git a/static/js/crypto-belt.js b/static/js/crypto-belt.js index c3f782a..dd6ec2d 100644 --- a/static/js/crypto-belt.js +++ b/static/js/crypto-belt.js @@ -22,6 +22,7 @@ class CryptoSubsystemVisualization { this.selectedCompetitionAlgorithm = 'AES'; this.algorithmModes = ['AES', 'SHA', 'CHACHA20']; this.selectedClientFilters = new Set(); + this.selectedRequesterFilter = null; } init(containerId = 'crypto-belt-container') { @@ -272,7 +273,9 @@ class CryptoSubsystemVisualization { btn.onclick = () => { const path = String(window.location.pathname || '').replace(/\/+$/, '') || '/'; - if (path === '/crypto' && window.history && typeof window.history.replaceState === 'function') { + if ((path === '/crypto' || path === '/linux-crypto-subsystem') + && window.history + && typeof window.history.replaceState === 'function') { window.history.replaceState({}, '', '/'); } if (window.kernelContextMenu) { @@ -764,19 +767,47 @@ class CryptoSubsystemVisualization { .attr('y', panelY + 56) .style('font-family', 'Share Tech Mono, monospace') .style('font-size', '9px') - .style('fill', '#8696ab') + .style('fill', '#708095') .text('none detected'); } else { requesters.forEach((req, idx) => { const reqName = String(req.name || 'unknown'); const reqKind = String(req.kind || 'generic'); const reqScore = Number(req.score || 0); - panel.append('text') + const isActiveRequester = Boolean( + this.selectedRequesterFilter + && String(this.selectedRequesterFilter.name || '').toLowerCase() === reqName.toLowerCase() + && String(this.selectedRequesterFilter.kind || '').toLowerCase() === reqKind.toLowerCase() + ); + const row = panel.append('g') + .style('cursor', 'pointer') + .on('click', () => { + if ( + this.selectedRequesterFilter + && String(this.selectedRequesterFilter.name || '').toLowerCase() === reqName.toLowerCase() + && String(this.selectedRequesterFilter.kind || '').toLowerCase() === reqKind.toLowerCase() + ) { + this.selectedRequesterFilter = null; + } else { + this.selectedRequesterFilter = { name: reqName, kind: reqKind }; + } + this.renderFlowMap(this.lastPayload || this.normalizeTelemetry(this.getFallbackTelemetry())); + }); + row.append('rect') + .attr('x', panelX + 10) + .attr('y', panelY + 46 + idx * 14) + .attr('width', panelW - 20) + .attr('height', 13) + .attr('rx', 3) + .style('fill', isActiveRequester ? 'rgba(37, 58, 92, 0.62)' : 'transparent') + .style('stroke', isActiveRequester ? 'rgba(120, 170, 245, 0.72)' : 'transparent') + .style('stroke-width', 0.8); + row.append('text') .attr('x', panelX + 14) .attr('y', panelY + 56 + idx * 14) .style('font-family', 'Share Tech Mono, monospace') .style('font-size', '9px') - .style('fill', idx === 0 ? '#cce2ff' : '#95a6bc') + .style('fill', isActiveRequester ? '#e1eeff' : (idx === 0 ? '#cce2ff' : '#95a6bc')) .text(`- ${reqName} [${reqKind}] (${reqScore})`); }); } @@ -1024,6 +1055,36 @@ class CryptoSubsystemVisualization { return false; } + laneMatchesSelectedRequester(lane) { + const req = this.selectedRequesterFilter; + if (!req) return true; + + const reqName = String(req.name || '').toLowerCase(); + const reqKind = String(req.kind || '').toLowerCase(); + const process = String(lane?.process || '').toLowerCase(); + const protocol = String(lane?.protocol || '').toUpperCase(); + const algo = String(lane?.algorithm || '').toLowerCase(); + + const selectedAlgo = String(this.selectedCompetitionAlgorithm || 'AES').toLowerCase(); + let algoMatch = true; + if (selectedAlgo === 'aes') { + algoMatch = algo.includes('aes') || protocol === 'TLS'; + } else if (selectedAlgo === 'sha') { + algoMatch = algo.includes('sha') || protocol === 'TLS'; + } else if (selectedAlgo === 'chacha20') { + algoMatch = algo.includes('chacha') || protocol === 'WIREGUARD' || protocol === 'SSH'; + } + if (!algoMatch) return false; + + if (reqKind === 'kernel-client') { + return this.laneMatchesClient(reqName, lane); + } + if (reqKind === 'process') { + return process.includes(reqName); + } + return process.includes(reqName) || protocol.toLowerCase().includes(reqName) || algo.includes(reqName); + } + drawNode(group, x, y, label, level, intensity, palette, emphasis) { const width = Math.min(Math.max(150, String(label).length * 8 + 28), 250); const height = 34; @@ -1129,7 +1190,9 @@ class CryptoSubsystemVisualization { this.drawStage1Panels(layer, payload?.meta || {}, width, height); const sourceLanes = Array.isArray(payload.items) ? payload.items : []; - const lanes = sourceLanes.filter((lane) => this.laneMatchesSelectedClients(lane)); + const lanes = sourceLanes.filter( + (lane) => this.laneMatchesSelectedClients(lane) && this.laneMatchesSelectedRequester(lane) + ); const topY = 150; const protocolY = 250; const cryptoY = 350; @@ -1145,6 +1208,9 @@ class CryptoSubsystemVisualization { const selectedLabel = this.selectedClientFilters.size ? Array.from(this.selectedClientFilters).join(' + ') : 'ALL'; + const requesterLabel = this.selectedRequesterFilter + ? ` | requester:${this.selectedRequesterFilter.name}` + : ''; layer.append('text') .attr('x', width * 0.42) .attr('y', 320) @@ -1152,13 +1218,13 @@ class CryptoSubsystemVisualization { .style('font-family', 'Share Tech Mono, monospace') .style('font-size', '12px') .style('fill', '#8fa0b6') - .text(`NO ACTIVE PATHS FOR ${selectedLabel.toUpperCase()}`); + .text(`NO ACTIVE PATHS FOR ${selectedLabel.toUpperCase()}${requesterLabel.toUpperCase()}`); } lanes.forEach((lane, idx) => { const x = startX + laneStep * idx; const intensity = Math.min(1 + lane.weight * 0.35, 2.2); - const emphasis = Boolean(lane.isNew || lane.isHot); + const emphasis = Boolean(lane.isNew || lane.isHot || this.selectedRequesterFilter); const laneGroup = layer.append('g').attr('class', 'crypto-lane'); const pNode = this.drawNode(laneGroup, x, topY, lane.process, 'process', intensity, lane.palette, emphasis); @@ -1221,9 +1287,18 @@ class CryptoSubsystemVisualization { .style('font-family', 'Share Tech Mono, monospace') .style('font-size', '11px') .style('fill', '#d2d9e5') - .text(this.selectedClientFilters.size - ? `ACTIVE PATHS (${Array.from(this.selectedClientFilters).join(' + ')})` - : 'ACTIVE PATHS'); + .text( + this.selectedClientFilters.size || this.selectedRequesterFilter + ? `ACTIVE PATHS (${[ + this.selectedClientFilters.size + ? Array.from(this.selectedClientFilters).join(' + ') + : null, + this.selectedRequesterFilter + ? `requester:${this.selectedRequesterFilter.name}` + : null + ].filter(Boolean).join(' | ')})` + : 'ACTIVE PATHS' + ); lanes.slice(0, 8).forEach((lane, idx) => { legend.append('text') @@ -1251,7 +1326,7 @@ class CryptoSubsystemVisualization { .attr('y', goneY + 16 + idx * 14) .style('font-family', 'Share Tech Mono, monospace') .style('font-size', '10px') - .style('fill', '#8e98a9') + .style('fill', '#8e98a9') .text(`- ${item.label} (${age}s)`); }); } diff --git a/static/js/main.js b/static/js/main.js index b7c7f4a..b029deb 100755 --- a/static/js/main.js +++ b/static/js/main.js @@ -92,10 +92,12 @@ function initApp() { // Setup event handlers setupEventListeners(); - // When nginx serves SPA fallback (/index.html) for /crypto, + // When nginx serves SPA fallback (/index.html) for crypto route aliases, // open the dedicated crypto view automatically by route. const path = String(window.location.pathname || '').replace(/\/+$/, '') || '/'; - if (path === '/crypto' && window.kernelContextMenu && typeof window.kernelContextMenu.activateCryptoView === 'function') { + if ((path === '/crypto' || path === '/linux-crypto-subsystem') + && window.kernelContextMenu + && typeof window.kernelContextMenu.activateCryptoView === 'function') { setTimeout(() => { window.kernelContextMenu.activateCryptoView(); }, 140); diff --git a/static/js/right-semicircle-menu.js b/static/js/right-semicircle-menu.js index 2e452c6..6b4b734 100644 --- a/static/js/right-semicircle-menu.js +++ b/static/js/right-semicircle-menu.js @@ -76,7 +76,7 @@ class RightSemicircleMenuManager { activateOverlayView(itemId) { if (itemId === 'scheduler') { // Force hard navigation to dedicated SEO page. - window.location.assign('/crypto'); + window.location.assign('/linux-crypto-subsystem'); return; } if (!window.kernelContextMenu) return; @@ -348,7 +348,7 @@ class RightSemicircleMenuManager { debugLog('🖱️ Click detected on item:', item.id, item.label); event.stopPropagation(); // Prevent event bubbling if (item.id === 'scheduler') { - window.location.assign('/crypto'); + window.location.assign('/linux-crypto-subsystem'); return; } if (isOverlay) { @@ -368,7 +368,7 @@ class RightSemicircleMenuManager { event.preventDefault(); event.stopPropagation(); if (item.id === 'scheduler') { - window.location.assign('/crypto'); + window.location.assign('/linux-crypto-subsystem'); return; } // Prevent re-rendering during click diff --git a/templates/linux-crypto-subsystem.html b/templates/linux-crypto-subsystem.html new file mode 100644 index 0000000..19510c2 --- /dev/null +++ b/templates/linux-crypto-subsystem.html @@ -0,0 +1,158 @@ + + + + + + Linux Crypto Kernel Subsystem - Linux Kernel Architecture Visualization + + + + + + + + + + + + + + + + + + + + + + + +

Linux Crypto Kernel Subsystem

+ +
+ +

Linux Crypto Kernel Subsystem

+

+ The Linux crypto kernel subsystem is part of the Linux kernel architecture responsible + for providing cryptographic primitives and services to kernel components and + userspace interfaces. The Linux crypto framework implements a unified API that + allows kernel modules and subsystems to request cryptographic algorithms such as + AES, ChaCha20, SHA256, and authenticated encryption modes like AES-GCM or + ChaCha20-Poly1305. +

+ +

Linux Kernel Crypto Architecture

+

+ Inside the Linux architecture the crypto subsystem works as a modular framework. + Kernel clients such as kTLS, WireGuard, dm-crypt, fscrypt, IPsec and AF_ALG + request cryptographic operations through the kernel crypto API. The subsystem + then performs algorithm lookup, implementation selection, and transform + allocation (tfm objects) before executing the operation using software or + hardware accelerated implementations. +

+ +

Algorithm Competition in Linux Crypto

+

+ One of the key mechanisms of the Linux crypto kernel subsystem is algorithm + competition. Multiple implementations of the same algorithm may be registered + in the kernel. For example AES can exist as generic software AES, AES-NI CPU + instructions, or SIMD optimized implementations. The crypto framework selects + the best implementation using priority values and hardware capability checks. +

+ +

Linux Crypto Hardware Acceleration

+

+ The Linux crypto subsystem can automatically use hardware acceleration + features available on modern CPUs. Examples include AES-NI instructions, + ARM crypto extensions, AVX vector acceleration, and dedicated crypto + accelerators. If hardware support is unavailable the subsystem automatically + falls back to software drivers. +

+ +

Linux Crypto Kernel Visualization

+

+ This page visualizes how the Linux crypto kernel subsystem works internally. + It shows the request origin process, protocol usage such as TLS or SSH, + crypto API interaction, transform lookup, algorithm competition, + implementation selection, and hardware offload status inside the Linux + kernel architecture. +

+ +
+ + + + + + + + +