From nobody Fri Aug 19 15:07:25 2022 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4M8Q9638lfz4ZLbN for ; Fri, 19 Aug 2022 15:07:38 +0000 (UTC) (envelope-from wlosh@bsdimp.com) Received: from mail-vk1-xa36.google.com (mail-vk1-xa36.google.com [IPv6:2607:f8b0:4864:20::a36]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4M8Q955k6mz4LFH for ; Fri, 19 Aug 2022 15:07:37 +0000 (UTC) (envelope-from wlosh@bsdimp.com) Received: by mail-vk1-xa36.google.com with SMTP id w129so2362382vkg.10 for ; Fri, 19 Aug 2022 08:07:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bsdimp-com.20210112.gappssmtp.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc; bh=akf8cEe/d0s1gg2a8CXhKrY6+gpr4z8hkax4VEquunk=; b=8VOnBJ3Jns/qyYqof0SkN13aAksVh5asExhaUKSduXHAADoU/c8h2IRvLk1BQ0boPw h3n7g78sKGd2hCF7jC/57tHZlL9tZHlus4xPnZqdOhip/jVwnO2kFekLHLNekgO0eNuU NnhZuBORX0vOhu85crLfmI/xof/+4Zbs/WqaRxXv6nEaRLup/wC5r0qDGM7jsCAj0i5A 3Rlycyk39rqq/cV3G3qqimyDLY1T2z+rWXhXKhmnWfvncIIwPrTxHhZr0kULrzq/TTGS QLrkiadpxGpJ8a9DHt23wt5EzUXJTrPWuMd1KQt+DG6cArLuzEwvwLWaShFTTsApQQJo M1xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc; bh=akf8cEe/d0s1gg2a8CXhKrY6+gpr4z8hkax4VEquunk=; b=2OH46zTT+1OaOEbkLOtn5LGF6SiM54v5JJrma6Q7oeKZ/AjNtlrXwonkzO8f0mmz4O 8LPtqigVouhl4xCIcBwz/i0aO4oLpNaOltFQloMx2ScT5Qwl4Psw8ZZQ3miIGLI00K1w 4aq9tbfPxQlv4jeqGMYFKv5uvHz0LxgD4sq10XFgWJLsOZpNDhgt+Op5TwDBVZKx56bE 8H0oCnHRgKrvQfTBKuDF9dho1108+b4EnHCxwRPD216RGLmc2V2dacD/4h047xqz77bB htmB4ttAM1J7fEgBXJ1UqyYiEv+teiP3ViJK8oCfH89hw/hoTLQ+X+RrgwayHYner5oM ytcQ== X-Gm-Message-State: ACgBeo3vSQSI6fEYooEHoMDHyp6ELtHOTKjUTZcWIN4000sKnDrU6U1b j9Ibd5yPA3/9LGjhvNXJSm878YxsFv+gTXaQNhvwFzB56CI= X-Google-Smtp-Source: AA6agR7T7Jfxnmx5CmHohqvAvS11necb//HqYEyprv0b4T6cWf8ejUKGvVSD651IYhfsS18gWp3oV8Dizd5qTAhLk8M= X-Received: by 2002:a1f:e3c5:0:b0:380:68eb:e647 with SMTP id a188-20020a1fe3c5000000b0038068ebe647mr3382493vkh.11.1660921656858; Fri, 19 Aug 2022 08:07:36 -0700 (PDT) List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@freebsd.org MIME-Version: 1.0 References: <1BFD8C02-370F-4E59-BC89-EEF970B44934@gvr.org> In-Reply-To: From: Warner Losh Date: Fri, 19 Aug 2022 09:07:25 -0600 Message-ID: Subject: Re: How to use serial console to enter GELI password to boot kernel on a GELI encrypted ZFS pool To: Guido van Rooij Cc: FreeBSD Hackers Content-Type: multipart/alternative; boundary="0000000000005b6f6205e699756c" X-Rspamd-Queue-Id: 4M8Q955k6mz4LFH X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org; dkim=pass header.d=bsdimp-com.20210112.gappssmtp.com header.s=20210112 header.b=8VOnBJ3J; dmarc=none; spf=none (mx1.freebsd.org: domain of wlosh@bsdimp.com has no SPF policy when checking 2607:f8b0:4864:20::a36) smtp.mailfrom=wlosh@bsdimp.com X-Spamd-Result: default: False [-2.50 / 15.00]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; NEURAL_HAM_SHORT(-1.00)[-1.000]; NEURAL_HAM_LONG(-1.00)[-0.999]; R_MIXED_CHARSET(0.50)[]; FORGED_SENDER(0.30)[imp@bsdimp.com,wlosh@bsdimp.com]; R_DKIM_ALLOW(-0.20)[bsdimp-com.20210112.gappssmtp.com:s=20210112]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; MLMMJ_DEST(0.00)[freebsd-hackers@freebsd.org]; R_SPF_NA(0.00)[no SPF record]; RCVD_TLS_LAST(0.00)[]; ASN(0.00)[asn:15169, ipnet:2607:f8b0::/32, country:US]; MIME_TRACE(0.00)[0:+,1:+,2:~]; RCVD_IN_DNSWL_NONE(0.00)[2607:f8b0:4864:20::a36:from]; DKIM_TRACE(0.00)[bsdimp-com.20210112.gappssmtp.com:+]; FROM_NEQ_ENVFROM(0.00)[imp@bsdimp.com,wlosh@bsdimp.com]; FROM_HAS_DN(0.00)[]; ARC_NA(0.00)[]; RCPT_COUNT_TWO(0.00)[2]; PREVIOUSLY_DELIVERED(0.00)[freebsd-hackers@freebsd.org]; TO_MATCH_ENVRCPT_SOME(0.00)[]; DMARC_NA(0.00)[bsdimp.com]; TO_DN_ALL(0.00)[]; RCVD_COUNT_TWO(0.00)[2] X-ThisMailContainsUnwantedMimeParts: N --0000000000005b6f6205e699756c Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Fri, Aug 19, 2022 at 2:20 AM Guido van Rooij wrote: > On Wed, Aug 17, 2022 at 09:19:42AM -0600, Warner Losh wrote: > > On Wed, Aug 17, 2022 at 7:35 AM Guido van Rooij <[1]guido@gvr.org> > > wrote: > > > > On 16 Aug 2022, at 19:09, Warner Losh <[2]imp@bsdimp.com> wrote: > > > > =C3=AF=C2=BB=C2=BF > > On Tue, Aug 16, 2022 at 3:44 AM Guido van Rooij <[3]guido@gvr.org> > > wrote: > > > > On Mon, Aug 15, 2022 at 02:20:32PM -0600, Warner Losh wrote: > > >=C3=82 =C3=82 On Mon, Aug 15, 2022 at 8:23 AM Guido van Rooij > > <[1][4]guido@gvr.org> > > >=C3=82 =C3=82 wrote: > > > > > >=C3=82 =C3=82 =C3=82 Currently I have a system with ZFS on GEL= I. I use the > > ability in > > >=C3=82 =C3=82 =C3=82 the EFI loader to enter the GELI password= . > > >=C3=82 =C3=82 =C3=82 Is it possible somehow to use a serial co= nsole to enter > > the > > >=C3=82 =C3=82 =C3=82 password? > > >=C3=82 =C3=82 =C3=82 My system does have a COM1 port but it is= n't recognised at > > the early > > >=C3=82 =C3=82 =C3=82 bot stage. There I only see: > > >=C3=82 =C3=82 =C3=82 =C3=83=C3=82 =C3=83=C3=82 Consoles: EFI= console > > >=C3=82 =C3=82 =C3=82 =C3=83=C3=82 =C3=83=C3=82 GELI Passphra= se for disk0p4: > > >=C3=82 =C3=82 =C3=82 (Note: this is early in the boot process = so there is no > > access to > > >=C3=82 =C3=82 =C3=82 boot.config (or any other file in the ZFS= pool) as it > > still on > > >=C3=82 =C3=82 =C3=82 encrypted storage at that time). > > > > > >=C3=82 =C3=82 The boot loader.efi will read ESP:/efi/freebsd/lo= ader.env for > > >=C3=82 =C3=82 environment > > >=C3=82 =C3=82 variables. You can use that to set the COM1 port = since it > > appears your > > >=C3=82 =C3=82 EFI system doesn't do console redirection. > > >=C3=82 =C3=82 If you want it to only prompt COM1 for the passwo= rd, but > > everything > > >=C3=82 =C3=82 else is > > >=C3=82 =C3=82 on the efi console, that's a lot harder. > > Hi Warner, > > Thanks, but somehow I still cannot get it to work properly. > > Content of /efi/freebsd/loader.env: > > boot_multicons=3D"YES" > > console=3D"efi comconsole" > > The boot prompt still only shows "Consoles: EFI console". > > > > Yes. That's printed before we process the ESP file and switch to the > > new console... > > =C3=82 > > > > When I boot I get the GELI passphrase prompt at the EFI console > > only. But when the kernel starts > > to run I do get output to the serial console, staring with: > > ---<>--- > > Copyright (c) 1992-2021 The FreeBSD Project. > > So it seems the loader.env file is read correctly (it didn't outpu= t > > anything to the serial > > console before I created efi/freebsd/loader.env). But looking at t= he > > source I see in > > efi/loader/main.c:read_loader_env(): > > =C3=82 =C3=82 =C3=82 =C3=82 if (fn) { > > =C3=82 =C3=82 =C3=82 =C3=82 =C3=82 =C3=82 =C3=82 =C3=82 pr= intf("=C3=82 =C3=82 Reading loader env vars from > > %s\n", fn); > > =C3=82 =C3=82 =C3=82 =C3=82 =C3=82 =C3=82 =C3=82 =C3=82 > > parse_loader_efi_config(boot_img->DeviceHandle, fn); > > =C3=82 =C3=82 =C3=82 =C3=82 } > > I never saw the printf appearing. I do not understand this. > > > > It should have appeared on the video console of the EFI console > > (assuming no serial > > redirect is going on in that BIOS). > > > > It surely did not. > > > > I'd have to delve more deeply into the prompts for the GELI password > > than I have > > time to do this morning. What if you type the password blind into th= e > > serial port? > > > > Tried that but nothing happened. When I > > enter the passphrase after typing it in via > > the serial port, it worked immediately so > > we can conclude that no single keystroke=C3=82 > > got through. > > > > OK. I'll have to delve a little more deeply then... > > I Think I know why it does not work. The "Consoles:" line is printed in > cons_probe() > which is called in main(): > setenv("console", "efi", 1); > cons_probe(); > So that explains why we see Consoles: EFI console > Then we see in main(): > for (i =3D 0; devsw[i] !=3D NULL; i++) > if (devsw[i]->dv_init !=3D NULL) > (devsw[i]->dv_init)(); > The way I understand it, is this the place where the GELI passphrase > prompt originates > from. > Well, not quite. We prompt for the GELI password when we first open a device in devopen (at least that's where we call geli_probe_and_attach())[*]. This should be a bit later, though. I'll have to put some debug prints in to see when it's called... But it looks like we probe for geli, according to the debug, at this point, so something needs to be done to sort out this chicken and egg problem. > But only after that, we see the call to load /efi/freebsd/loader.env > > Shouldn't the dv_init() calls be moved to after the call to > boot_howto_to_env(howto)? > You have discovered a wonderful chicken and egg. If we don't call dv_init we can't do I/O to the devices, so we can't change the console. But, the boot_hwoto_to_env() call only sets env variables that will be used to either set boot args to the kernel or other env variables that are used to communicate the console. It doesn't actually change the console, so is the wrong thing to locate. The likely best way to approach this is to fix loader.efi to initialize enough of the devices so that we can read files off the ESP early enough to set a good console for further interaction. Warner [*] this leads to a bit of a layering violation that causes a circular dependency, but I digress... --0000000000005b6f6205e699756c Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Fri, Aug 19, 2022 at 2:20 AM Guido= van Rooij <guido@gvr.org> wrote= :
On Wed, Aug 17= , 2022 at 09:19:42AM -0600, Warner Losh wrote:
>=C2=A0 =C2=A0 On Wed, Aug 17, 2022 at 7:35 AM Guido van Rooij <[1]guido@gvr.org>
>=C2=A0 =C2=A0 wrote:
>
>=C2=A0 =C2=A0 =C2=A0 On 16 Aug 2022, at 19:09, Warner Losh <[2]imp@bsdimp.com> wrote= :
>
>=C2=A0 =C2=A0 =C3=AF=C2=BB=C2=BF
>=C2=A0 =C2=A0 On Tue, Aug 16, 2022 at 3:44 AM Guido van Rooij <[3]guido@gvr.org>
>=C2=A0 =C2=A0 wrote:
>
>=C2=A0 =C2=A0 =C2=A0 On Mon, Aug 15, 2022 at 02:20:32PM -0600, Warner L= osh wrote:
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 On Mon, Aug 15, 2022= at 8:23 AM Guido van Rooij
>=C2=A0 =C2=A0 =C2=A0 <[1][4]guido@gvr.org>
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 wrote:
>=C2=A0 =C2=A0 =C2=A0 >
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 Current= ly I have a system with ZFS on GELI. I use the
>=C2=A0 =C2=A0 =C2=A0 ability in
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 the EFI= loader to enter the GELI password.
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 Is it p= ossible somehow to use a serial console to enter
>=C2=A0 =C2=A0 =C2=A0 the
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 passwor= d?
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 My syst= em does have a COM1 port but it isn't recognised at
>=C2=A0 =C2=A0 =C2=A0 the early
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 bot sta= ge. There I only see:
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=83= =C3=82=C2=A0 =C3=83=C3=82=C2=A0 Consoles: EFI console
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=83= =C3=82=C2=A0 =C3=83=C3=82=C2=A0 GELI Passphrase for disk0p4:
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 (Note: = this is early in the boot process so there is no
>=C2=A0 =C2=A0 =C2=A0 access to
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 boot.co= nfig (or any other file in the ZFS pool) as it
>=C2=A0 =C2=A0 =C2=A0 still on
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 encrypt= ed storage at that time).
>=C2=A0 =C2=A0 =C2=A0 >
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 The boot loader.efi = will read ESP:/efi/freebsd/loader.env for
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 environment
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 variables. You can u= se that to set the COM1 port since it
>=C2=A0 =C2=A0 =C2=A0 appears your
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 EFI system doesn'= ;t do console redirection.
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 If you want it to on= ly prompt COM1 for the password, but
>=C2=A0 =C2=A0 =C2=A0 everything
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 else is
>=C2=A0 =C2=A0 =C2=A0 >=C3=82=C2=A0 =C3=82=C2=A0 on the efi console, = that's a lot harder.
>=C2=A0 =C2=A0 =C2=A0 Hi Warner,
>=C2=A0 =C2=A0 =C2=A0 Thanks, but somehow I still cannot get it to work = properly.
>=C2=A0 =C2=A0 =C2=A0 Content of /efi/freebsd/loader.env:
>=C2=A0 =C2=A0 =C2=A0 boot_multicons=3D"YES"
>=C2=A0 =C2=A0 =C2=A0 console=3D"efi comconsole"
>=C2=A0 =C2=A0 =C2=A0 The boot prompt still only shows "Consoles: E= FI console".
>
>=C2=A0 =C2=A0 Yes. That's printed before we process the ESP file an= d switch to the
>=C2=A0 =C2=A0 new console...
>=C2=A0 =C2=A0 =C3=82
>
>=C2=A0 =C2=A0 =C2=A0 When I boot I get the GELI passphrase prompt at th= e EFI console
>=C2=A0 =C2=A0 =C2=A0 only. But when the kernel starts
>=C2=A0 =C2=A0 =C2=A0 to run I do get output to the serial console, star= ing with:
>=C2=A0 =C2=A0 =C2=A0 ---<<BOOT>>---
>=C2=A0 =C2=A0 =C2=A0 Copyright (c) 1992-2021 The FreeBSD Project.
>=C2=A0 =C2=A0 =C2=A0 So it seems the loader.env file is read correctly = (it didn't output
>=C2=A0 =C2=A0 =C2=A0 anything to the serial
>=C2=A0 =C2=A0 =C2=A0 console before I created efi/freebsd/loader.env). = But looking at the
>=C2=A0 =C2=A0 =C2=A0 source I see in
>=C2=A0 =C2=A0 =C2=A0 efi/loader/main.c:read_loader_env():
>=C2=A0 =C2=A0 =C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2= =A0 if (fn) {
>=C2=A0 =C2=A0 =C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2= =A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 printf("=C3=82= =C2=A0 =C3=82=C2=A0 Reading loader env vars from
>=C2=A0 =C2=A0 =C2=A0 %s\n", fn);
>=C2=A0 =C2=A0 =C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2= =A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82
>=C2=A0 =C2=A0 =C2=A0 parse_loader_efi_config(boot_img->DeviceHandle,= fn);
>=C2=A0 =C2=A0 =C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2=A0 =C3=82=C2= =A0 }
>=C2=A0 =C2=A0 =C2=A0 I never saw the printf appearing. I do not underst= and this.
>
>=C2=A0 =C2=A0 It should have appeared on the video console of the EFI c= onsole
>=C2=A0 =C2=A0 (assuming no serial
>=C2=A0 =C2=A0 redirect is going on in that BIOS).
>
>=C2=A0 =C2=A0 It surely did not.
>
>=C2=A0 =C2=A0 I'd have to delve more deeply into the prompts for th= e GELI password
>=C2=A0 =C2=A0 than I have
>=C2=A0 =C2=A0 time to do this morning. What if you type the password bl= ind into the
>=C2=A0 =C2=A0 serial port?
>
>=C2=A0 =C2=A0 Tried that but nothing happened. When I
>=C2=A0 =C2=A0 enter the passphrase after typing it in via
>=C2=A0 =C2=A0 the serial port, it worked immediately so
>=C2=A0 =C2=A0 we can conclude that no single keystroke=C3=82
>=C2=A0 =C2=A0 got through.
>
>=C2=A0 =C2=A0 OK. I'll have to delve a little more deeply then...
I Think I know why it does not work. The "Consoles:" line is prin= ted in cons_probe()
which is called in main():
=C2=A0 =C2=A0 =C2=A0 =C2=A0 setenv("console", "efi", 1)= ;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 cons_probe();
So that explains why we see Consoles: EFI console
Then we see in main():
=C2=A0 =C2=A0 =C2=A0 =C2=A0 for (i =3D 0; devsw[i] !=3D NULL; i++)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (devsw[i]->dv= _init !=3D NULL)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (devsw[i]->dv_init)();
The way I understand it, is this the place where the GELI passphrase prompt= originates
from.

Well, not quite. We prompt for th= e GELI password when we first open a device in devopen
(at least = that's where we call geli_probe_and_attach())[*]. This should be a bit = later, though.
I'll have to put some debug prints in to see w= hen it's called... But it looks like we probe for
geli, accor= ding to the debug, at this point, so something needs to be done to sort out= this
chicken and egg problem.
=C2=A0
But only after that, we see the call to load /efi/freebsd/loader.env

Shouldn't the dv_init() calls be moved to after the call to boot_howto_= to_env(howto)?

You have discovered a wo= nderful chicken and egg. If we don't call dv_init we can't do I/O
to the devices, so we can't change the console.

=
But, the boot_hwoto_to_env() call only sets env variables that w= ill be used to either set
boot args to the kernel or other env va= riables that are used to communicate the console.
It doesn't = actually change the console, so is the wrong thing to locate.
The likely best way to approach this is to fix loader.efi to in= itialize enough of the devices
so that we can read files off the = ESP early enough to set a good console for further
interaction.

Warner

[*] this leads to a= bit of a layering violation that causes a circular dependency, but I digre= ss...
--0000000000005b6f6205e699756c--