d0a4059102
This restores the original version of delocate.go, with the subsequent bugfixes patched in. With this, the FIPS module builds with GCC and Clang, with and without optimizations. I did patch over a variant of the macro though, since it was otherwise really wordy. Playing games with sections was a little overly clever and relied on the compiler not performing a number of optimizations. Clang blew threw all of those assumptions. Change-Id: Ib4da468a5925998457994f9e392cf0c04573fe91 Reviewed-on: https://boringssl-review.googlesource.com/14805 Reviewed-by: Adam Langley <agl@google.com>
110 lines
3.0 KiB
Go
110 lines
3.0 KiB
Go
// Copyright (c) 2017, Google Inc.
|
|
//
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
// copyright notice and this permission notice appear in all copies.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
|
|
// inject-hash runs a binary compiled against a FIPS module that hasn't had the
|
|
// correct hash injected. That binary will fail the power-on integrity check
|
|
// and write the calcualted hash value to stderr. This script parses that and
|
|
// injects the calcualted value into the given object file.
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
func do(outPath, arInput, binPath string) error {
|
|
cmd := exec.Command(binPath)
|
|
out, err := cmd.CombinedOutput()
|
|
|
|
if err == nil {
|
|
return errors.New("binary did not fail self test")
|
|
}
|
|
|
|
lines := strings.Split(string(out), "\n")
|
|
if len(lines) < 3 {
|
|
return fmt.Errorf("too few lines in output: %q", out)
|
|
}
|
|
|
|
calculatedLine := lines[2]
|
|
if !strings.HasPrefix(calculatedLine, "Calculated: ") {
|
|
return errors.New("bad prefix of 3rd line: " + calculatedLine)
|
|
}
|
|
calculatedLine = calculatedLine[12:]
|
|
calculated, err := hex.DecodeString(calculatedLine)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(calculated) != len(uninitHashValue) {
|
|
return fmt.Errorf("unexpected length of calculated hash: got %d, want %d", len(calculated), len(uninitHashValue))
|
|
}
|
|
|
|
arFile, err := os.Open(arInput)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer arFile.Close()
|
|
|
|
ar, err := ParseAR(arFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(ar) != 1 {
|
|
return fmt.Errorf("expected one file in archive, but found %d", len(ar))
|
|
}
|
|
|
|
var object []byte
|
|
for _, contents := range ar {
|
|
object = contents
|
|
}
|
|
|
|
offset := bytes.Index(object, uninitHashValue[:])
|
|
if offset < 0 {
|
|
return errors.New("did not find uninitialised hash value in object file")
|
|
}
|
|
|
|
if bytes.Index(object[offset+1:], uninitHashValue[:]) >= 0 {
|
|
return errors.New("found two occurrences of uninitialised hash value in object file")
|
|
}
|
|
|
|
copy(object[offset:], calculated)
|
|
|
|
if err := ioutil.WriteFile(outPath, object, 0644); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
arInput := flag.String("in", "", "Path to a .a file")
|
|
outPath := flag.String("o", "", "Path to output object")
|
|
bin := flag.String("bin", "", "Binary compiled with the FIPS module")
|
|
|
|
flag.Parse()
|
|
|
|
if err := do(*outPath, *arInput, *bin); err != nil {
|
|
fmt.Fprintf(os.Stderr, "%s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|