arch/x86/entry/vdso/vdso64/vgetrandom-chacha.S

Source file repositories/reference/linux-study-clean/arch/x86/entry/vdso/vdso64/vgetrandom-chacha.S

File Facts

System
Linux kernel
Corpus path
arch/x86/entry/vdso/vdso64/vgetrandom-chacha.S
Extension
.S
Size
4119 bytes
Lines
179
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: arch/x86
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2022-2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 */

#include <linux/linkage.h>
#include <asm/frame.h>

.section	.rodata, "a"
.align 16
CONSTANTS:	.octa 0x6b20657479622d323320646e61707865
.text

/*
 * Very basic SSE2 implementation of ChaCha20. Produces a given positive number
 * of blocks of output with a nonce of 0, taking an input key and 8-byte
 * counter. Importantly does not spill to the stack. Its arguments are:
 *
 *	rdi: output bytes
 *	rsi: 32-byte key input
 *	rdx: 8-byte counter input/output
 *	rcx: number of 64-byte blocks to write to output
 */
SYM_FUNC_START(__arch_chacha20_blocks_nostack)

.set	output,		%rdi
.set	key,		%rsi
.set	counter,	%rdx
.set	nblocks,	%rcx
.set	i,		%al
/* xmm registers are *not* callee-save. */
.set	temp,		%xmm0
.set	state0,		%xmm1
.set	state1,		%xmm2
.set	state2,		%xmm3
.set	state3,		%xmm4
.set	copy0,		%xmm5
.set	copy1,		%xmm6
.set	copy2,		%xmm7
.set	copy3,		%xmm8
.set	one,		%xmm9

	/* copy0 = "expand 32-byte k" */
	movaps		CONSTANTS(%rip),copy0
	/* copy1,copy2 = key */
	movups		0x00(key),copy1
	movups		0x10(key),copy2
	/* copy3 = counter || zero nonce */
	movq		0x00(counter),copy3
	/* one = 1 || 0 */
	movq		$1,%rax
	movq		%rax,one

.Lblock:
	/* state0,state1,state2,state3 = copy0,copy1,copy2,copy3 */
	movdqa		copy0,state0
	movdqa		copy1,state1
	movdqa		copy2,state2
	movdqa		copy3,state3

	movb		$10,i
.Lpermute:
	/* state0 += state1, state3 = rotl32(state3 ^ state0, 16) */
	paddd		state1,state0
	pxor		state0,state3
	movdqa		state3,temp
	pslld		$16,temp
	psrld		$16,state3
	por		temp,state3

Annotation

Implementation Notes