AMD Steppe Eagle: Add 32-bit Fletcher's Checksum computation
The AMD Platform Security Processor (PSP) requires a Fletcher's Checksum at the end of the PSP directory. This code implements a Fletcher's Checksum by reading bytes from stdin and writes the bytes back to stdout with a checksum inserted into the byte stream at the appropriate offset. This utility is used on PSP binaries during coreboot build. Include a runtime debug option such that the command: fletcher --print <file.bin >file_with_cksum.bin will print out the computed checksum value for debugging. The compile-time debug option is retained that allows -DDEBUG to be added to the compilation line. This option has the same effect as "--print". Change-Id: I506a479d8204ca4f8267d53aa152ac4b473dbc75 Signed-off-by: Bruce Griffith <Bruce.Griffith@se-eng.com> Reviewed-on: http://review.coreboot.org/6676 Reviewed-by: WANG Siyuan <wangsiyuanbuaa@gmail.com> Tested-by: build bot (Jenkins) Reviewed-by: Zheng Bao <zheng.bao@amd.com>
This commit is contained in:
parent
71c0bf6202
commit
3a2310e05c
|
@ -0,0 +1,37 @@
|
||||||
|
#*****************************************************************************
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014, Sage Electronic Engineering, LLC
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of Advanced Micro Devices, Inc. nor the names of
|
||||||
|
# its contributors may be used to endorse or promote products derived
|
||||||
|
# from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
|
||||||
|
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
#*****************************************************************************
|
||||||
|
HOSTCC ?= gcc
|
||||||
|
|
||||||
|
fletcher_exe : fletcher.c
|
||||||
|
$(HOSTCC) fletcher.c -o fletcher
|
||||||
|
|
||||||
|
fletcher : fletcher_exe
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f fletcher.o fletcher fletcher.exe
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1998-2006 The TCPDUMP project
|
||||||
|
* 2014 Sage Electronic Engineering, LLC
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that: (1) source code
|
||||||
|
* distributions retain the above copyright notice and this paragraph
|
||||||
|
* in its entirety, and (2) distributions including binary code include
|
||||||
|
* the above copyright notice and this paragraph in its entirety in
|
||||||
|
* the documentation or other materials provided with the distribution.
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
|
||||||
|
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||||
|
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* Original code by Hannes Gredler <hannes@juniper.net>
|
||||||
|
* Rewritten for Fletcher32 by Bruce Griffith <Bruce.Griffith@se-eng.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define MAX_PSP_DIRECTORY_SIZE 512
|
||||||
|
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates the OSI Fletcher checksum. See 8473-1, Appendix C, section C.3.
|
||||||
|
* The checksum field of the passed PDU does not need to be reset to zero.
|
||||||
|
*
|
||||||
|
* The "Fletcher Checksum" was proposed in a paper by John G. Fletcher of
|
||||||
|
* Lawrence Livermore Labs. The Fletcher Checksum was proposed as an
|
||||||
|
* alternative to cyclical redundancy checks because it provides error-
|
||||||
|
* detection properties similar to cyclical redundancy checks but at the
|
||||||
|
* cost of a simple summation technique. Its characteristics were first
|
||||||
|
* published in IEEE Transactions on Communications in January 1982. One
|
||||||
|
* version has been adopted by ISO for use in the class-4 transport layer
|
||||||
|
* of the network protocol.
|
||||||
|
*
|
||||||
|
* This program expects:
|
||||||
|
* stdin: The input file to compute a checksum for. The input file
|
||||||
|
* not be longer than 256 bytes.
|
||||||
|
* stdout: Copied from the input file with the Fletcher's Checksum
|
||||||
|
* inserted 8 bytes after the beginning of the file.
|
||||||
|
* stderr: Used to print out error messages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t fletcher32 (const uint16_t *pptr, int length)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t c0;
|
||||||
|
uint32_t c1;
|
||||||
|
uint32_t checksum;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
c0 = 0xFFFF;
|
||||||
|
c1 = 0xFFFF;
|
||||||
|
|
||||||
|
for (index = 0; index < length; index++) {
|
||||||
|
/*
|
||||||
|
* Ignore the contents of the checksum field.
|
||||||
|
*/
|
||||||
|
c0 += *(pptr++);
|
||||||
|
c1 += c0;
|
||||||
|
if ((index % 360) == 0) {
|
||||||
|
c0 = (c0 & 0xFFFF) + (c0 >> 16); // Sum0 modulo 65535 + the overflow
|
||||||
|
c1 = (c1 & 0xFFFF) + (c1 >> 16); // Sum1 modulo 65535 + the overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
c0 = (c0 & 0xFFFF) + (c0 >> 16); // Sum0 modulo 65535 + the overflow
|
||||||
|
c1 = (c1 & 0xFFFF) + (c1 >> 16); // Sum1 modulo 65535 + the overflow
|
||||||
|
checksum = (c1 << 16) | c0;
|
||||||
|
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint32_t checksum = 0xFFFFFFFF;
|
||||||
|
struct stat filestat = {};
|
||||||
|
int retcode = EINVAL;
|
||||||
|
size_t filesize = 0;
|
||||||
|
char debugoption[] = "--print";
|
||||||
|
|
||||||
|
uint16_t buffer[MAX_PSP_DIRECTORY_SIZE / sizeof(uint16_t)];
|
||||||
|
|
||||||
|
retcode = fstat(fileno(stdin), &filestat);
|
||||||
|
filesize = filestat.st_size;
|
||||||
|
if (retcode < 0) {
|
||||||
|
perror("FLETCHER32");
|
||||||
|
return errno;
|
||||||
|
} else if (!((12 < filesize) && (filesize <= sizeof(buffer)))) {
|
||||||
|
fprintf(stderr, "FLETCHER32: input file is not valid for this program.\n");
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
retcode = read(fileno(stdin), (void *)buffer, filesize);
|
||||||
|
if (retcode < 0) {
|
||||||
|
perror("FLETCHER32");
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum = fletcher32(&buffer[2], filesize/2 - 2);
|
||||||
|
*((uint32_t *)& buffer[2]) = checksum;
|
||||||
|
#ifndef DEBUG
|
||||||
|
if ((argc == 2) && !strncmp(argv[1], debugoption, sizeof(debugoption+1))) {
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "Fletcher's Checksum: %x\n", checksum);
|
||||||
|
#ifndef DEBUG
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
retcode = write(fileno(stdout), buffer, filesize);
|
||||||
|
if (retcode < 0) {
|
||||||
|
perror("FLETCHER32");
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue