SHA-256 (Secure Hash Algorithm 256-bit)

SHA-256 is a cryptographic hash function that produces a fixed-size 256-bit (32-byte) hash. It is deterministic, collision-resistant, and designed for security-critical applications. How SHA-256 Works Preprocessing: Pad the input to a multiple of 512 bits. Append a 1, then add k zeros, and finally append the original message length (64 bits). Initialize Hash Values: Use constants derived from the fractional parts of square roots of the first 8 primes (eight 32-bit words). Example: h0 = 0x6a09e667, h1 = 0xbb67ae85, .... Process Blocks: Split the padded message into 512-bit blocks. For each block: Expand the block into 64 words using a message schedule. Perform 64 rounds of compression using bitwise operations (e.g., XOR, AND, modular addition). Compression Function A compression function is applied to each block, creating a new hash value. This function involves mixing the bits of the current hash value and the message block. Iteration Repeat the compression function for each block, using the output of each iteration as input for the next. Final Hash: Combine the intermediate hash values to produce the final 256-bit digest. Example: SHA-256 for String “Hello” Input: “Hello” → ASCII 48656C6C6F. Padding: Length = 40 bits (5 bytes). Pad with 1, 407 zeros, and 0000000000000028 (hex for 40 bits). Hash Computation: After processing, the final hash is: 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969. Use Cases SHA-256 Cryptographic security in: Digital signatures (SSL/TLS certificates). Password storage (hashed+salted). Blockchain (Bitcoin transactions). File integrity verification (e.g., software downloads). Guarantees: Pre-image resistance, collision resistance.

January 29, 2025 · 2 min

CRC (Cyclic Redundancy Check)

CRC is an error-detection code used to detect accidental changes to raw data (e.g., during transmission or storage). It works by treating the data as a polynomial and performing polynomial division with a predefined generator polynomial. The remainder of this division becomes the CRC value. How CRC is Calculated Convert data to binary: Treat the data as a sequence of bits. Append zeros: Add n zeros to the end of the data, where n is the degree of the generator polynomial (e.g., CRC-32 uses a 33-bit polynomial, so append 32 zeros). Polynomial division: Divide the data + zeros by the generator polynomial using modulo-2 arithmetic (XOR operations). CRC value: The remainder of this division is the CRC checksum. Example: CRC-8 for String “Hi” Data: “Hi” in ASCII is 01001000 01101001. Generator Polynomial: CRC-8 (e.g., x⁸ + x² + x + 1), represented as 100000111. Append 8 zeros: Data becomes 010010000110100100000000. Perform division: Divide 010010000110100100000000 by 100000111 using XOR. Remainder: Let’s assume the remainder is 00110110 (hex 0x36). Final CRC: 0x36. Use Cases Error detection in: Network protocols (Ethernet, Wi-Fi). Storage systems (hard drives, ZIP files). Quick checksums for small data transfers. Not secure against intentional tampering.

January 29, 2025 · 1 min

Device Tree (DT) in Linux Kernel

Overview The Device Tree (DT) is a data structure used to describe the hardware components of a system in a way that is independent of the operating system and software. It is particularly relevant for systems based on the ARM architecture, where the hardware varies significantly across devices. Instead of hardcoding hardware details in the kernel, the device tree provides a flexible way to inform the kernel about the system’s hardware layout. This simplifies kernel code and enables easier reuse across multiple hardware platforms. ...

January 27, 2025 · 5 min

Character Device Management in Kernel Drivers

Overview Character devices allow byte-by-byte communication between user-space applications and kernel drivers. They are commonly used for devices like serial ports, sensors, and custom hardware interfaces. The Linux kernel provides mechanisms for registering, managing, and interacting with character devices via a device file in /dev. Registering a Character Device To register a character device, the driver needs to: 1. Allocate a Major and Minor Number: Each character device is identified by a major number (device type) and a minor number (specific device). The major number indicates the driver associated with the device, while the minor number is used to differentiate between multiple devices handled by the same driver. If major and minor numbers are repeated, it can cause conflicts and lead to incorrect device identification. To avoid this, the kernel provides alloc_chrdev_region, a function to dynamically allocate major and minor numbers, ensuring uniqueness. These numbers are used in the /dev directory to associate device files with their corresponding drivers. Use alloc_chrdev_region to dynamically allocate a major number. dev_t dev; int result; // kernel/fs/char_dev.c // int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name) result = alloc_chrdev_region(&dev, 0, 1, "my_char_device"); if (result < 0) { pr_err("Failed to allocate major number\n"); return result; } pr_info("Device registered with major %d, minor %d\n", MAJOR(dev), MINOR(dev)); 2. Initialize and Register the Device: Define a cdev structure and initialize it with file operations. Use cdev_add to register the device with the kernel. struct cdev my_cdev; cdev_init(&my_cdev, &my_fops); my_cdev.owner = THIS_MODULE; result = cdev_add(&my_cdev, dev, 1); if (result < 0) { pr_err("Failed to add cdev\n"); unregister_chrdev_region(dev, 1); return result; } 3. Create a Device File (Optional): Creating a device file in /dev is optional because character devices can be accessed directly using their major and minor numbers through system calls or user-space libraries, bypassing the need for a device file. However, creating a file in /dev makes interaction more user-friendly by providing a standard interface. To interact with a character device without creating a device file, you can use system calls like mknod to create a temporary device node or interact with the device directly using its major and minor numbers programmatically. Use class_create and device_create to automatically create a device file in /dev. struct class *my_class; my_class = class_create(THIS_MODULE, "my_device_class"); if (IS_ERR(my_class)) { pr_err("Failed to create class\n"); cdev_del(&my_cdev); unregister_chrdev_region(dev, 1); return PTR_ERR(my_class); } device_create(my_class, NULL, dev, NULL, "my_char_device"); File Operations Character devices are controlled through a set of file operations defined in a struct file_operations. These operations determine how the device responds to system calls like open, read, write, and ioctl. ...

January 24, 2025 · 4 min

IOCTL in Kernel Device Drivers

ioctl Implementation in Kernel Device Drivers Overview ioctl (Input/Output Control) is a powerful system call in Linux used to perform device-specific operations that are not covered by standard system calls like read, write, or open. It allows user-space applications to interact with kernel-space drivers for device-specific configurations and data exchanges. How ioctl Works 1. User-Space Interaction: A user-space application invokes ioctl using the following prototype: int ioctl(int fd, unsigned long cmd, void *arg); fd: File descriptor for the device. cmd: Command defining the operation. arg: Pointer to the data or argument passed between user-space and kernel-space. 2. Driver-Side Handling: The ioctl system call is routed to the driver by the kernel. The driver implements a specific unlocked_ioctl or compat_ioctl callback in the file_operations structure. 3. Data Flow: Arguments passed via arg can be pointers to user-space data, requiring the driver to use helper functions like copy_from_user and copy_to_user for secure data transfer. Steps to Implement ioctl in a Kernel Driver 1. Define ioctl Commands: Use macros to define command numbers, typically with the _IO, _IOR, _IOW, and _IOWR macros provided in <linux/ioctl.h>. #define MY_IOCTL_BASE 'M' #define IOCTL_CMD_GET _IOR(MY_IOCTL_BASE, 1, int) #define IOCTL_CMD_SET _IOW(MY_IOCTL_BASE, 2, int) _IOR: Read data from the kernel. _IOW: Write data to the kernel. _IOWR: Read and write data. _IO: Command without data. 2. Implement ioctl Callback: Define the unlocked_ioctl function in the driver. Handle commands appropriately based on cmd. static long my_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int value; switch (cmd) { case IOCTL_CMD_GET: value = 1234; // Example value if (copy_to_user((int __user *)arg, &value, sizeof(value))) return -EFAULT; break; case IOCTL_CMD_SET: if (copy_from_user(&value, (int __user *)arg, sizeof(value))) return -EFAULT; pr_info("Value set by user: %d\n", value); break; default: return -ENOTTY; // Command not supported } return 0; } 3. Integrate into file_operations: Register the ioctl handler in the file_operations structure. static const struct file_operations my_fops = { .owner = THIS_MODULE, .open = my_open, .release = my_release, .unlocked_ioctl = my_ioctl, }; 4. Test the ioctl Implementation: Write a user-space application to interact with the driver. #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #define MY_IOCTL_BASE 'M' #define IOCTL_CMD_GET _IOR(MY_IOCTL_BASE, 1, int) #define IOCTL_CMD_SET _IOW(MY_IOCTL_BASE, 2, int) int main() { int fd, value = 42; fd = open("/dev/my_device", O_RDWR); if (fd < 0) { perror("Failed to open device"); return -1; } if (ioctl(fd, IOCTL_CMD_SET, &value) < 0) { perror("ioctl SET failed"); } if (ioctl(fd, IOCTL_CMD_GET, &value) < 0) { perror("ioctl GET failed"); } else { printf("Value from device: %d\n", value); } close(fd); return 0; } Best Practices for ioctl Use Explicit Command Definitions: Follow a consistent naming convention for command macros. Secure User-Kernel Data Transfer: Always validate pointers and sizes. Use copy_from_user and copy_to_user for safe data exchange. Error Handling: Return appropriate error codes for unsupported commands or invalid inputs. Limit ioctl Usage: Avoid using ioctl for operations that can be implemented using read or write. Magic Number: Ensure it’s unique (check Documentation/ioctl/ioctl-number.txt in kernel sources). Atomicity: Use locks if hardware operations are not atomic. Cross-Platform: Handle 32/64-bit compatibility with compat_ioctl if needed. Real-World Example: Custom ARM Board For a custom ARM board, you might need an ioctl to configure hardware parameters like GPIO modes or clock frequencies. ...

January 24, 2025 · 4 min

SSL Certificate

An SSL certificate is a digital certificate issued by a trusted third-party authority known as a Certificate Authority (CA). It verifies the identity of a website or server and enables secure, encrypted communication. Components of an SSL Certificate Public Key: Used for encryption and verifying the certificate’s authenticity. Certificate Holder Information: Details like the domain name, organization, and location. Issuer Information: The CA that issued the certificate. Validity Period: Specifies the time frame during which the certificate is valid. Digital Signature: Ensures the certificate was issued by a trusted CA and has not been tampered with. Self-Signed Certificates Examples and Differences Type Usage Example Difference Self-Signed Internal servers, testing Generated via OpenSSL Not trusted by default in browsers or OS. CA-Signed Public-facing servers Issued by DigiCert, Let’s Encrypt Trusted by browsers and OS. Wildcard Certificate Secures a domain and its subdomains *.example.com Can’t be self-signed, requires a CA. Multi-Domain Certificate Covers multiple domains example.com, test.com Self-signed possible but not widely used. Self-Signed Certificates A self-signed certificate is a digital certificate that is not issued by a trusted Certificate Authority (CA) but is signed by the entity it is certifying (e.g., your own server). These certificates are primarily used for internal testing, development environments, or scenarios where external trust is not required. ...

December 10, 2024 · 3 min

SSL(Secure Socket Layer)

Its purpose is to ensure that all data transmitted between the server and the client remains private and secure from eavesdropping, tampering, or forgery. While SSL itself has been deprecated in favor of its successor, TLS (Transport Layer Security), the term “SSL” is still commonly used to refer to the broader concept of secure network communication.

December 10, 2024 · 1 min

Short Term Trading - After result

Overall Idea Avoid immediate trading post-result; monitor price behaviour instead. Monitor for retracement and consistent trends See quarterly result and shortlist high growth stocks Fundamental Analysis is must because if the analysis is even wrong but fundamentals are strong then the loss will be minimal. So, less chance of being wrong. Filter by Fundamentals High Growth Criteria: Quarterly sales growth YoY > 10%. Quarterly profit growth YoY > 10%. Sales and profit in the latest quarter should be the highest compared to previous quarters. See percent change in growth of past 3 years ...

December 8, 2024 · 3 min

TradingView Shortcuts

Alt + H = Horizontal line Alt + V = Vertical line Alt + T = Trendline Alt + F = Fibonacci Alt + C = Crossline Alt + I = Invert chart Alt + S = Link to your chart References https://www.tradingview.com/charting-library-docs/latest/getting_started/Shortcuts/

December 8, 2024 · 1 min

Problem - fw_printenv does not print bootloader env variables

Problem In bootloader the environment variables are accessible. The values could be accessed and modified perfectly from bootloader cli (hush shell). When booting to the linux kernel and accessing from bash shell (userspace) through fw_printenv the environment variables are not accessible. Getting following logs: Warning: Bad CRC, using default environment Setup: Using MMC storage The /etc/fw_env.config file has following entry and the offset and size are same from uboot’s .config file /dev/mmcblk0p2 0x3f8000 0x8000 Uboot Environment in RK3588 Uboot Config config ENV_OFFSET hex "Environment offset" depends on !ENV_IS_IN_UBI depends on !ENV_IS_NOWHERE || ENVF default 0x0 if ENVF default 0x3f8000 help Offset from the start of the device (or partition) config ENV_SIZE hex "Environment size" default 0x8000 help Size of the environment storage area Parameters CONFIG_ENV_SIZE=0x8000 --> 32K CONFIG_ENV_OFFSET=0x3f8000 --> 4096-32=4064 4096K=4M u-boot/tools/env/fw_env.c Either crc0_ok = (crc0 == *environment.crc); is invalid ...

December 4, 2024 · 4 min