From 80b82fdfc41fea15096ef902321acf879ab4f9f7 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 6 Aug 2016 17:13:22 -0400 Subject: [PATCH] extract and verify gpg signature on the boot script --- Makefile | 23 +++++++++++-- initrd/mount-boot | 71 +++++++++++++++++++++++++++++++++++++++++ initrd/trustedkeys.gpg | Bin 0 -> 17559 bytes 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100755 initrd/mount-boot create mode 100644 initrd/trustedkeys.gpg diff --git a/Makefile b/Makefile index 22034aff..45fdc499 100644 --- a/Makefile +++ b/Makefile @@ -80,8 +80,8 @@ initrd_bins += initrd/bin/$(notdir $1) endef $(foreach _, $(call outputs,kexec), $(eval $(call initrd_bin,$_))) -$(foreach _, $(call outputs,tpmtotp), $(eval $(call initrd_bin,$_))) -$(foreach _, $(call outputs,xen), $(eval $(call initrd_bin,$_))) +#$(foreach _, $(call outputs,tpmtotp), $(eval $(call initrd_bin,$_))) +#$(foreach _, $(call outputs,xen), $(eval $(call initrd_bin,$_))) # hack to install busybox into the initrd initrd_bins += initrd/bin/busybox @@ -101,10 +101,21 @@ initrd/bin/cbmem: $(build)/$(coreboot_dir)/util/cbmem/cbmem $(build)/$(coreboot_dir)/util/cbmem/cbmem: $(build)/$(coreboot_dir)/.canary make -C "$(dir $@)" +# Mounting dm-verity file systems requires dm-verity to be installed +# We use gpgv to verify the signature on the root hash. +# Both of these should be brought in as modules instead of from /sbin +initrd_bins += initrd/bin/dmsetup +initrd/bin/dmsetup: /sbin/dmsetup + cp "$<" "$@" +initrd_bins += initrd/bin/gpgv +initrd/bin/gpgv: /usr/bin/gpgv + cp "$<" "$@" # Update all of the libraries in the initrd based on the executables # that were installed. initrd_libs: $(initrd_bins) + -find initrd/bin -type f -print0 \ + | xargs -0 strip ./populate-lib \ ./initrd/lib/x86_64-linux-gnu/ \ initrd/bin/* \ @@ -122,6 +133,8 @@ initrd_libs: $(initrd_bins) # # If there is in /dev/console, initrd can't startup. # We have to force it to be included into the cpio image. +# Since we are picking up the system's /dev/console, the +# timestamp will not be reproducible. # # initrd.cpio: $(initrd_bins) initrd_libs @@ -154,3 +167,9 @@ $(build)/$(coreboot_dir)/bzImage: $(call outputs,linux) cp -a "$^" "$@" $(call outputs,coreboot): $(build)/$(coreboot_dir)/bzImage + +# The CoreBoot gcc won't work for us since it doesn't have libc +#XGCC := $(build)/$(coreboot_dir)/util/crossgcc/xgcc/ +#export CC := $(XGCC)/bin/x86_64-elf-gcc +#export LDFLAGS := -L/lib/x86_64-linux-gnu + diff --git a/initrd/mount-boot b/initrd/mount-boot new file mode 100755 index 00000000..5f2d3515 --- /dev/null +++ b/initrd/mount-boot @@ -0,0 +1,71 @@ +#!/bin/sh +# Extract the GPG signed dmsetup configuration from +# the header of the file system, validate it against +# the trusted key database, and execute it to mount +# the /boot filesystem + +dev="$1" +offset="$2" + +cmd=/tmp/mount-boot +cmd_sig="$cmd.asc" + +if [ -z "$dev" ]; then + dev=/dev/sda +fi + +if [ -z "$offset" ]; then + offset=256 +fi + +# +# Find the size of the device +# Is there a better way? +# +dev_size_file="/sys/class/block/`basename $dev`/size" +if [ ! -r "$dev_size_file" ]; then + echo >&2 '!!!!!' + echo >&2 '!!!!! $dev file $dev_size_file not found' + echo >&2 '!!!!! Dropping to recovery shell' + echo >&2 '!!!!!' + exit -1 +fi + +dev_blocks=`cat "$dev_size_file"` + +# +# Extract the signed file from the hard disk image +# +if ! dd if="$dev" of="$cmd_sig" bs=512 skip="`expr $dev_blocks - 1`"; then + echo >&2 '!!!!!' + echo >&2 '!!!!! Boot block extraction failed' + echo >&2 '!!!!! Dropping to recovery shell' + echo >&2 '!!!!!' + exit -1 +fi + +# +# Validate the file +# +if ! gpgv --keyring /trustedkeys.gpg "$cmd_sig"; then + echo >&2 '!!!!!' + echo >&2 '!!!!! GPG signature on block failed' + echo >&2 '!!!!! Dropping to recovery shell' + echo >&2 '!!!!!' + exit -1 +fi + +# +# Strip the PGP signature off the file +# (too bad gpgv doesn't do this) +# +awk < "$cmd_sig" > "$cmd" ' + /BEGIN PGP SIGNATURE/ { exit }; + do_print {print}; + /^$/ { do_print=1 }; +' + +# +# And execute it! +# +sh -x "$cmd" diff --git a/initrd/trustedkeys.gpg b/initrd/trustedkeys.gpg new file mode 100644 index 0000000000000000000000000000000000000000..3381d1de094d1747e193cd7dbd19ed2767761bfc GIT binary patch literal 17559 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

4Fx@sZblQ-5e{B? zGE*zg2u+D8H|bF}^%aXPQ;BoyI6jj#xr8%2u3v#vaWuQhAR;^d(ujctV_Ic2Qe(Z^ zX6cQcDz*}o+e6B)UAZ!pC;3M`a-V1yfu}k;Rsh=0-d)8RuzUBGm))LibDO8&@O7$m8ORwcK|5Y)_jKNU+=&#L^-7iv^?= zmxe%2l8lj8X+qS@v>;ko!FGghzckOM7yIIpUn=~g??@Bt73&R!Hh4M_4ItpQe?JOw zq~YS~hVPW#?&&ue`zdEiZF&DV4^qCTXY6d5B9P23n9T3&Dey`fBCG3Y`H6jAv;0x> z&y?QJ#J@&aoAz17b?_0wqzSq@KMbwUrW8AE zMtw*EvokiU4@^8;6|pf#R|d5at|yQG6YKrGmG-}5y?6-tZ$jt0MC|AE@Is1VRX;5` zG+egP*Vl3QxApPE(scJrYxgeC-kJu8S*pA)U5;$O6kdmQdn!WhX>cL0s{zOn$7;Q* zBX|WfTJ;_&tBa}0gp8mM3&kPOXz%Dg5ObQuSB^r_VkhS6T=n)v-?R7T_Guz&=j&Z5 zL>f=A`q@AFgQl)Sz0*mhDd*}v<=O!2$1*+9RtdPDZ{eT8R-cl8#W)7advOEax&3gGX$mz5M2QDms`RIb=*|u#yowVJ-flrCgzvGW+Nf zSw^$pmKRA(QpA$a!0Y)XLaCSMnzPa%R1E#Yf}Oz$?5dG86q2Hn8rTccnn9~b#>c%pA3c;Jt04F>)GG!X?z2XErAD24j6#s~HU+;5@zYX= z#kGz+1To0V<3Xh{eg$NSCrp#zQ|gS`&juN90RTP&s2#8<+ukj8D~F@e9P%qC@+~9A zx-1W)Ud^|9*uy?s>LZe$DQxF@rn`q75&}}?CMipvq1I^gnrd#NjWmNgbI%eLm9a!c zGf0OOD#ND0e4zv&LK(3{jX_fv)VH`QA_{c0)aRr%;J9AAXo|&UbB`^oFb~@+CF2H+ zk!T_7=Y)+dF7;0r+Fn!nBx`hp(pJX6j%H#^eRTYDpYiwjr|}||HA$A>PrtS@|HXOR zbKZ_*N}5n>=`JcWA!#IuD6H(W?iHAx`oSXPWU=cdH$!X{<&#Tm}4{sxus0(K!{#`C)2L{ z%Sh ztsF7c??s5Erf@DV!b_QKWY?<1aiW=7pmu-RTGIjVOm0v5yN}mwXQhgPsU17y_H-pO z(Q*FO*H<9hAKcAs?8P{4#fLxfz=6d!dQotu-NONk)hWOP(?y~wLdaJZ<<{YZBJ5Mp zBK}>JHitH|uk8CBW%H=Xtz*xCJiGxIYL`g-oa;@F(E*bo{$!uSD`MUsY3~LXH~Nmc zJ0h_HBsm!(=ZfTvziHi5Is}t-w zJ)_~rNe_Rz1H+{E>KKsBRz<4g;lvYIzM6CGF(u94J+zM`(Re^m+`t+Ev5FL^jf_I{jaR~@QI+qP$ zEf;S^8)Sogj>lVQD0M$d6dl3lk8J4x1AfnEiK}>HUm9g{@E?SP6_@3aORd)>i;-h_ zaN>%pD2(!)D)NE>gfNg+Q)q+F^3M^-Z6J|$Cdh66s=z9x_ds0JPh3l>Am-b(-;Y2s zckUIhp>JFgkUTpK$R?k+#A6Zj%LVIqkHZ;s6zu#1L(%Vd1|E9Ox*)&H)E^Xi;%+z= zm%0wEvDBE9pap+{G^#6y)x>v&%f#ZuK6P=*l3IcqNa>`~RagU};qmLyYeRz~TIJ7K zJ{r2U&VE#{TQ{tj=z7&VIGH6T&!`WHbjHQb_qa!Q_0HVaZY{qSjz=ReeNMhl+`eZW zb^yYHsF-cM{k8sewB#oZFaF&VjdJXKGO_bWP%cwOA}+ZT-M#dC4V%Fp54|;cuQstR zD@}iSz2{@wDHC^!kyL_ZYo@d!W6Bo~T4|Wy@0#DD@<63U$@^1Bk{KbENS%4rA znrC*LYR-jIwiL!N?%n_!vACe!jH7rjVEVjw-5UClQq0`CPJV*WBEl>bOek5qeVo0C zDC^i~%)KJ`-}44o|MPcB!KVZ$ z{l4n8fGY$4(QCy)nLQ$GF)hXRr7E=HRLbt>WZ_HGiAhZz=I&(Mf(d^!;)cjkJAIH? zz%OXDiJfUQNED=xF6ZHD-4Ej`*UN^z|2>t+2biBSNkw|5PH~U5CRy1~-2U0JbbyM% zaNVQaS@Y|+DbaGe0cq9^R?zKvy!=nu^MzgP+aE$Z;L?YM28EoM0%bRq-T4oa;s78J zQ8kbPHeG~n4ERtORO>(G=RFFen}!~NCuX>bxVXE&lpUV(Kd%jUxj+SH?TJ5n9R%nM z;Jn|+{&YWi6~%H8eTbd?p7t6Lx~yBa3DaFhnu)&Dg+y&g#G6ZsEwjiha?=e8yuRka z`f0uyNj53@YwM@#h_MhIAfl9_lDAi!qY|pd zqh^NG7PIg#&FDQ8wHLv~!lyus?ZQmHPpuMV(neI`6~z2@q?%4&pPTj#uJ z#R@4rnKKUO41I3Twe&3PF7~Z4T91{#4-(Y0m?lksIZGR(hv1M$i^rq^9&kiPF%o_y zD!-c;=b~Z4KCB>mLGPG!tgwYFSn%H)S;`NlVzvuN+dj2Pt)$6HmM7P8CF=NMwrz(O zIUqeLd@4(@fK`h{ezSUlQ8oh!2Y9Do$rHYPzLfFnK$shRSBh}zY_w0K&GqVjE0bfP zad>iHT3T@-#;-#2g-8>R7(i;9!_&(S7fg3dAv(Rd&tTmV2_GR(*1Zl--P<-zX*Dc@ z=~bzHAu1;(xgoBJ`+D+15wEACH>#w3g=;HCJoUcmlan{Zfp4(!4#ABYZpEv~wUAuE z%ko0hh+U=w_oiEhf><4Pl2cUSE&o6*o14GeF@xIqmcCoco9VFECg#{M!O*}0EsS0G zPx(0ew}6z?I63oW!hsx+p>HfV33#b4MfHn62Fj+sTt%JniH$x^<9uA13XwN(tz1}Y zixdC*wXzBQ*R_(*pbBk6y?~>;D}_SkTx+F&wReCyR6}zprBse+07skKH0BqSfMs#Y z#f6Nx!#uI*mP~afZ^^qR22dMi?C&gpd$lZ)YB;%Ra6lzT%HLcDJzhO)VXpv`c#1Xf zY4h#^6IvjE`YEu0Zg8|zb4cd?wT_2v1l$X4hyIDn} zp=bk}KIZ)YUyfDGHlhEm9RGc-{O58krw9Mz8TjBZW}Im6*;H6RW?rIfcb#=3zVu~4 zW*uqx2h^Y7PZ~yI6|J{j5ilZVt? zG7f=#YFG3Gmr+&-d2*4hP|xUDW1E}^_#)M?AggB@8taFE$UW?odb)|c^S?S^$$(xpWTAB zWJI=My`+Y){rv@z<;e0VsO0QX<0^>n4_5-J7q>=*wgmT0xZBEM;(1qCgHU2nbfG#g zgypvz{`z-{ws^B3YlmELtd_cEyykMAy?KGpyb9NDidg?wkq`MwY3?+1$<0dWyf7UV zzuI+=K)f`0J}EA4ECf!~dP**P94*2>SVoDUrvYidTmgNaRRTLE@4gc3du@_8h_xvO ZqogWD_T