Hi Joel,

On Tue, Feb 8, 2022 at 6:46 PM Joel Stanley <j...@jms.id.au> wrote:
>
> Hello Troy,
>
> On Wed, 12 Jan 2022 at 08:10, Troy Lee <troy_...@aspeedtech.com> wrote:
> >
> > Accumulative mode will supply a initial state and append padding bit at
> > the end of hash stream.  However, the crypto library will padding those
> > bit automatically, so ripped it off from iov array.
> >
> > The aspeed ast2600 acculumative mode is described in datasheet
> > ast2600v10.pdf section 25.6.4:
> >  1. Allocationg and initiating accumulative hash digest write buffer
> >     with initial state.
> >     * Since QEMU crypto/hash api doesn't provide the API to set initial
> >       state of hash library, and the initial state is already setted by
> >       crypto library (gcrypt/glib/...), so skip this step.
> >  2. Calculating accumulative hash digest.
> >     (a) When receiving the last accumulative data, software need to add
> >         padding message at the end of the accumulative data. Padding
> >         message described in specific of MD5, SHA-1, SHA224, SHA256,
> >         SHA512, SHA512/224, SHA512/256.
> >         * Since the crypto library (gcrypt/glib) already pad the
> >           padding message internally.
> >         * This patch is to remove the padding message which fed byguest
> >           machine driver.
>
>
> I tested the latest aspeed SDK u-boot, loaded form mmc (with our mmc
> model that lives in Cedric's tree) and qemu crashed:
>
> #0  0x00007fe867d44932 in ?? () from 
> /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
> #1  0x0000557aba2b6e22 in qcrypto_glib_hash_bytesv (alg=<optimized
> out>, iov=0x7fe8662ee0b0, niov=1, result=0x7fe8662ee0a8,
> resultlen=0x7fe8662ee0a0, errp=0x0) at ../crypto/hash-glib.c:68
> #2  0x0000557ab9f549ea in do_hash_operation (s=s@entry=0x7fe866e1b3b0,
> algo=5, sg_mode=sg_mode@entry=true, acc_mode=acc_mode@entry=true) at
> ../hw/misc/aspeed_hace.c:161
> #3  0x0000557ab9f54dd1 in aspeed_hace_write (opaque=<optimized out>,
> addr=12, data=262504, size=<optimized out>) at
> ../hw/misc/aspeed_hace.c:260
>
> WIthout your patch applied the HACE operation fails, as we do not have
> support for accumulative mode, but we do not crash.

I'll double check on this issue.

> >
> > Changes in v2:
> > - Coding style
> > - Add accumulative mode description in comment
> >
> > Signed-off-by: Troy Lee <troy_...@aspeedtech.com>
> > ---
> >  hw/misc/aspeed_hace.c         | 43 ++++++++++++++++++++++++++++-------
> >  include/hw/misc/aspeed_hace.h |  1 +
> >  2 files changed, 36 insertions(+), 8 deletions(-)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> > index 10f00e65f4..0710f44621 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -11,6 +11,7 @@
> >  #include "qemu/osdep.h"
> >  #include "qemu/log.h"
> >  #include "qemu/error-report.h"
> > +#include "qemu/bswap.h"
> >  #include "hw/misc/aspeed_hace.h"
> >  #include "qapi/error.h"
> >  #include "migration/vmstate.h"
> > @@ -27,6 +28,7 @@
> >
> >  #define R_HASH_SRC      (0x20 / 4)
> >  #define R_HASH_DEST     (0x24 / 4)
> > +#define R_HASH_KEY_BUFF (0x28 / 4)
> >  #define R_HASH_SRC_LEN  (0x2c / 4)
> >
> >  #define R_HASH_CMD      (0x30 / 4)
> > @@ -94,7 +96,8 @@ static int hash_algo_lookup(uint32_t reg)
> >      return -1;
> >  }
> >
> > -static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode)
> > +static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
> > +                              bool acc_mode)
> >  {
> >      struct iovec iov[ASPEED_HACE_MAX_SG];
> >      g_autofree uint8_t *digest_buf;
> > @@ -103,6 +106,7 @@ static void do_hash_operation(AspeedHACEState *s, int 
> > algo, bool sg_mode)
> >
> >      if (sg_mode) {
> >          uint32_t len = 0;
> > +        uint32_t total_len = 0;
> >
> >          for (i = 0; !(len & SG_LIST_LEN_LAST); i++) {
> >              uint32_t addr, src;
> > @@ -123,10 +127,26 @@ static void do_hash_operation(AspeedHACEState *s, int 
> > algo, bool sg_mode)
> >                                          MEMTXATTRS_UNSPECIFIED, NULL);
> >              addr &= SG_LIST_ADDR_MASK;
> >
> > -            iov[i].iov_len = len & SG_LIST_LEN_MASK;
> > -            plen = iov[i].iov_len;
> > +            plen = len & SG_LIST_LEN_MASK;
> >              iov[i].iov_base = address_space_map(&s->dram_as, addr, &plen, 
> > false,
> >                                                  MEMTXATTRS_UNSPECIFIED);
> > +
> > +            if (acc_mode) {
> > +                total_len += plen;
> > +
> > +                if (len & SG_LIST_LEN_LAST) {
> > +                    /*
> > +                     * In the padding message, the last 64/128 bit 
> > represents
> > +                     * the total length of bitstream in big endian.
> > +                     * SHA-224, SHA-256 are 64 bit
> > +                     * SHA-384, SHA-512, SHA-512/224, SHA-512/256 are 128 
> > bit
> > +                     * However, we would not process such a huge bit 
> > stream.
> > +                     */
> > +                    plen -= total_len - (ldq_be_p(iov[i].iov_base + plen - 
> > 8) / 8);
> > +                }
> > +            }
> > +
> > +            iov[i].iov_len = plen;
> >          }
> >      } else {
> >          hwaddr len = s->regs[R_HASH_SRC_LEN];
> > @@ -210,6 +230,9 @@ static void aspeed_hace_write(void *opaque, hwaddr 
> > addr, uint64_t data,
> >      case R_HASH_DEST:
> >          data &= ahc->dest_mask;
> >          break;
> > +    case R_HASH_KEY_BUFF:
> > +        data &= ahc->key_mask;
> > +        break;
> >      case R_HASH_SRC_LEN:
> >          data &= 0x0FFFFFFF;
> >          break;
> > @@ -229,12 +252,13 @@ static void aspeed_hace_write(void *opaque, hwaddr 
> > addr, uint64_t data,
> >          }
> >          algo = hash_algo_lookup(data);
> >          if (algo < 0) {
> > -                qemu_log_mask(LOG_GUEST_ERROR,
> > -                        "%s: Invalid hash algorithm selection 
> > 0x%"PRIx64"\n",
> > -                        __func__, data & ahc->hash_mask);
> > -                break;
> > +            qemu_log_mask(LOG_GUEST_ERROR,
> > +                    "%s: Invalid hash algorithm selection 0x%"PRIx64"\n",
> > +                    __func__, data & ahc->hash_mask);
> > +            break;
> >          }
> > -        do_hash_operation(s, algo, data & HASH_SG_EN);
> > +        do_hash_operation(s, algo, data & HASH_SG_EN,
> > +                ((data & HASH_HMAC_MASK) == HASH_DIGEST_ACCUM));
> >
> >          if (data & HASH_IRQ_EN) {
> >              qemu_irq_raise(s->irq);
> > @@ -333,6 +357,7 @@ static void aspeed_ast2400_hace_class_init(ObjectClass 
> > *klass, void *data)
> >
> >      ahc->src_mask = 0x0FFFFFFF;
> >      ahc->dest_mask = 0x0FFFFFF8;
> > +    ahc->key_mask = 0x0FFFFFC0;
> >      ahc->hash_mask = 0x000003ff; /* No SG or SHA512 modes */
> >  }
> >
> > @@ -351,6 +376,7 @@ static void aspeed_ast2500_hace_class_init(ObjectClass 
> > *klass, void *data)
> >
> >      ahc->src_mask = 0x3fffffff;
> >      ahc->dest_mask = 0x3ffffff8;
> > +    ahc->key_mask = 0x3FFFFFC0;
> >      ahc->hash_mask = 0x000003ff; /* No SG or SHA512 modes */
> >  }
> >
> > @@ -369,6 +395,7 @@ static void aspeed_ast2600_hace_class_init(ObjectClass 
> > *klass, void *data)
> >
> >      ahc->src_mask = 0x7FFFFFFF;
> >      ahc->dest_mask = 0x7FFFFFF8;
> > +    ahc->key_mask = 0x7FFFFFF8;
> >      ahc->hash_mask = 0x00147FFF;
> >  }
> >
> > diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
> > index 94d5ada95f..2242945eb4 100644
> > --- a/include/hw/misc/aspeed_hace.h
> > +++ b/include/hw/misc/aspeed_hace.h
> > @@ -37,6 +37,7 @@ struct AspeedHACEClass {
> >
> >      uint32_t src_mask;
> >      uint32_t dest_mask;
> > +    uint32_t key_mask;
> >      uint32_t hash_mask;
> >  };
> >
> > --
> > 2.25.1
> >

Reply via email to