xref: /aosp_15_r20/external/vboot_reference/scripts/keygeneration/vbprivk_to_pem.sh (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1#!/bin/bash
2# Copyright 2024 The ChromiumOS Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5#
6# Generates PEM encoded private key from a .vbprivk
7
8# Load common constants and functions.
9# shellcheck source=common.sh
10# shellcheck disable=SC1091
11. "$(dirname "$0")/common.sh"
12
13set -eu -o pipefail
14
15usage() {
16	cat <<EOF
17Usage: $0 [options]
18
19Options:
20	--input <file>          vbprivk private key (default: stdin)
21	--output <file>         PEM encoded private key (default: stdout)
22EOF
23
24	if [[ $# -ne 0 ]]; then
25		die "unknown option $*"
26	else
27		exit 0
28	fi
29}
30
31# Reads a signed 64 bit integer from stdin
32readi64() {
33	local output
34	output="$(od --address-radix=none --read-bytes=8 --format=d8)"
35	# Drop leading padding and zeros
36	echo "$(("${output}"))"
37}
38
39main() {
40	local input_fd=0 # stdin
41	local output_fd=1 # stdout
42	while [[ $# -gt 0 ]]; do
43		case $1 in
44		--input)
45			if ! exec 3< "$2"; then
46				die "Failed to open input file '$2'"
47			fi
48			input_fd=3
49			shift
50			;;
51		--output)
52			if ! exec 4> "$2"; then
53				die "Failed to open output file '$2'"
54			fi
55			output_fd=4
56			shift
57			;;
58		-h|--help)
59			usage
60			;;
61		*)
62			usage "$1"
63			;;
64		esac
65		shift
66	done
67
68	# A `vbprivk` is comprised of an 8 byte header followed by a DER encoded
69	# PKCS#1 RSA Private Key. We read the 8 byte header from the input_fd
70	# (which increments file position) and verify that it's a sane value.
71	#
72	# See /vboot_reference/firmware/2lib/include/2crypto.h
73	local vb2_crypto_algorithm
74	vb2_crypto_algorithm="$(readi64 <&"${input_fd}")"
75
76	if [[ "${vb2_crypto_algorithm}" -lt 0 || \
77			"${vb2_crypto_algorithm}" -gt 17 ]]; then
78		die "Unknown vbprivk format"
79	fi
80
81	# Convert the remainder of the input_fd to base64.
82	echo -n "-----BEGIN RSA PRIVATE KEY-----
83$(base64 --wrap=64 <&"${input_fd}")
84-----END RSA PRIVATE KEY-----
85" >&"${output_fd}"
86}
87main "$@"
88